【问题标题】:Query on EXECUTE sp_executesql查询 EXECUTE sp_executesql
【发布时间】:2019-10-08 10:02:56
【问题描述】:

我试图让@sqlstring 根据其他文件中可用的月份运行 3 次,这些结果都与#table 合并。

  1. 当我包含“memberid in ('00001', '00002','00003')”时,错误消息是“'00001' 附近的语法不正确”。
  2. 当我排除 memberid 时,错误消息是“Msg 214, Level 16, State 3, Procedure sp_executesql, Line 1 [Batch Start Line 1268] 过程需要 'ntext/nchar/nvarchar' 类型的参数 '@params'。"

如何解决以下查询?

DECLARE @Month VARCHAR(2)
DECLARE @Month1 VARCHAR(2)
DECLARE @Month2 VARCHAR(2)
DECLARE @Month3 VARCHAR(2)
DECLARE @Year VARCHAR(4)
DECLARE @Year1 VARCHAR(4)
DECLARE @Year2 VARCHAR(4)
DECLARE @Year3 VARCHAR(4)
DECLARE @SQLSTRING NVARCHAR(MAX)

SET @MONTH1 = N'SELECT MONTH FROM #period WHERE ROW = 1' 
SET @MONTH2 = N'SELECT MONTH FROM #period WHERE ROW = 2' 
SET @MONTH3 = N'SELECT MONTH FROM #period WHERE ROW = 3' 
SET @YEAR1 = N'SELECT YEAR FROM #period WHERE ROW = 1' 
SET @YEAR2 = N'SELECT YEAR FROM #period WHERE ROW = 2' 
SET @YEAR3 = N'SELECT YEAR FROM #period WHERE ROW = 3' 

SET @SQLSTRING = N'select memberid, sales, @MONTH as month, @YEAR as svyear
from member@Month where month = @month and memberid in ('00001', '00002','00003')'


INSERT INTO #table
EXECUTE sp_executesql @SQLSTRING, @MONTH=@MONTH1, @YEAR=@YEAR1
INSERT INTO #table
EXECUTE sp_executesql @SQLSTRING, @MONTH=@MONTH2, @YEAR=@YEAR2
INSERT INTO #table
EXECUTE sp_executesql @SQLSTRING, @MONTH=@MONTH3, @YEAR=@YEAR3;

【问题讨论】:

  • 你为什么将DECLARE变量作为varchar(2)(或(4)),然后尝试将SET它们的值作为nvarchar远大于 2/4 个字符?
  • 您也永远不会分配@Month@Year 的值。也许样本数据和预期结果将帮助我们更好地了解您的真正目标是什么。
  • 作为提示,在尝试执行该语句之前,请通过选择变量 SQLSTRING、MONTH1 和 YEAR1 来帮助自己。我认为这可能会让您明白为什么会出错。
  • @Larnu,#period 中有两列,年和月(数字)。里面只有三行数据。我想根据#period 中出现的值从表'member_#month'中提取数据。假设如果 #period 中出现了第 1 个月和第 2 个月,那么我需要从表 member_1 和 member_2 中提取数据。
  • 您不能准备部分查询字符串作为参数。您需要将整个查询构建为字符串 - 您没有要作为参数传递的值。是的,SQL 注入警告适用。

标签: sql-server tsql


【解决方案1】:

首先,您必须创建临时表。您对临时表的插入必须在您的 sql 查询中。

然后使用带有转义字符的查询,如下所示:

SET @SQLSTRING = N'INSERT INTO #table
select memberid, sales, @MONTH as month, @YEAR as svyear
from member where month = @MONTH and memberid in (''00001'', ''00002'',''00003'')'

最后调用函数:

DECLARE @sParams nvarchar(512) = '@MONTH VARCHAR(2), @YEAR VARCHAR(4)';

EXEC sp_executesql @SQLSTRING, @sParams, @MONTH, @YEAR;

【讨论】:

  • 这并没有解决实际上是DECLARE @Month1 VARCHAR(2) = N'SELECT MONTH FROM #period WHERE ROW = 1' 的问题。 39 个字符长的文字 nvarchar 永远不会在 varchar(2) 中找到。
  • @Larnu 是的,你是对的,并在上面的评论中写道,但我在这里提到了更多错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多