为什么NVarchar(MAX)不能使用SP_ExecuteSQL执行完整的动态查询?
我创建了一个包含两个查询的存储过程,这两个查询将更新两个表中的记录 所以我会提到它显示了什么 我的程序如下为什么NVarchar(MAX)不能使用SP_ExecuteSQL执行完整的动态查询?,sql,sql-server,stored-procedures,dynamic,sp-executesql,Sql,Sql Server,Stored Procedures,Dynamic,Sp Executesql,我创建了一个包含两个查询的存储过程,这两个查询将更新两个表中的记录 所以我会提到它显示了什么 我的程序如下 ALTER PROC UpdateMissingItemONPoe @StoreID INT, @Name VARCHAR(20) AS BEGIN DECLARE @UpdateRec NVARCHAR(MAX) = ''; DECLARE @StoreIP SYSNAME = '' SET @StoreIP = CASE @StoreID
ALTER PROC UpdateMissingItemONPoe
@StoreID INT,
@Name VARCHAR(20)
AS
BEGIN
DECLARE @UpdateRec NVARCHAR(MAX) = '';
DECLARE @StoreIP SYSNAME = ''
SET @StoreIP = CASE @StoreID
WHEN 1111 THEN '[192.168.1.45].[Store1].[dbo]'
WHEN 2222 THEN '[192.168.2.45].[Store2].[dbo]'
WHEN 3333 THEN '[192.168.3.45].[Store3].[dbo]'
END
SET @UpdateRec = N' IF((SELECT NameID from '+@StoreIP+'.Details WHERE Name = '''+@Name+''') = 2 )
BEGIN
INSERT INTO ' + @StoreIP + '.PurchaseOrderEntry(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
SubDescription,
Rank
from
'+@StoreIP+'.Details
where
Name = '''+@Name+'''
INSERT INTO '+@StoreIP+'.HeadQuarter(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
SubDescription,
Rank
from
'+@StoreIP+'.Details
where
Name = '''+@Name+'''
END'
print @UpdateRec
EXEC sp_executesql @UpdateRec
END
当我执行此存储过程时,它不会显示任何错误消息。但是,当我打印时,动态查询没有完整的查询
打印的查询就像
INSERT INTO '+@StoreIP+'.PurchaseOrderEntry(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
SubDescription,
Rank
from
'+@StoreIP+'.Details
where
Name = '''+@Name+'''
INSERT INTO '+@StoreIP+'.HeadQuarter(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
其余的行丢失了我将其改写为:
ALTER PROC UpdateMissingItemONPoe
@StoreID INT,
@Name VARCHAR(20)
AS
BEGIN
DECLARE @UpdateRec NVARCHAR(MAX) = N'';
DECLARE @StoreIP NVARCHAR(128) = N'';
SET @StoreIP = CASE @StoreID
WHEN 1111 THEN '[192.168.1.45].[Store1].[dbo]'
WHEN 2222 THEN '[192.168.2.45].[Store2].[dbo]'
WHEN 3333 THEN '[192.168.3.45].[Store3].[dbo]'
END;
SET @UpdateRec = N' IF((SELECT NameID from <@StoreIP>.Details
WHERE Name = @Name) = 2 )
BEGIN
INSERT INTO <StoreIP>.PurchaseOrderEntry(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
SubDescription,
Rank
from
<@StoreIP>.Details
where
Name = @Name
INSERT INTO <@StoreIP>.HeadQuarter(
/* InsertField Name */
)
select
Name,
Standard,
Department,
Category,
SubDescription,
Rank
from
<@StoreIP>.Details
where
Name = @Name
END';
SET @UpdateRec = REPLACE(@UpadteRec, N'<@StoreIP>', @StoreIp);
print @UpdateRec
EXEC sp_executesql @UpdateRec, N'@Name NVARCHAR(20)', @Name;
END
使用参数化的动态SQL并使用替换而不是连接来交换表名。您的查询肯定超过了4000个字符 将SET语句更改为
SET @UpdateRec = CONVERT(NVARCHAR(MAX), '') + N' IF(('
如果。。。到nvarcharmax 过去,如果这些多部分语句没有显式转换为nvarchar4000类型,SQL Server会将它们转换为nvarchar4000 如果你有一个变量
DECLARE @UpdateRec NVARCHAR(MAX) = '';
然后使用这种语法
SET @UpdateRec = N' IF((SELECT NameID from '+@StoreIP+'.Details WHERE
Name = '''+@Name+''') = 2 ) BEGIN
INSERT INTO ' + @StoreIP + '.PurchaseOrderEntry( (...)'
结果将无声地转换为nvarchar4000,并将在没有警告的情况下截断任何多余的字符。@marc\s你知道吗?@UpdateRec的长度是多少?print@UpdateRec可能无法打印@UpdateRec中的所有内容,这取决于中的设置SSMS@Squirrel我提到过。这是NVarcharMAXCan无法在SQL Server 2016上复制的-打印输出正确地显示了@StoreIP被替换为案例中正确的预期值,并且输出包含所有行…@Liamneesan,不仅打印的查询被截断,IF语句丢失,变量未正确连接。您发布的代码将无条件地包含这些内容,并按预期为我运行。我怀疑你实际执行的程序与你问题中的程序不同。我按照你提到的那样做了。现在长度显示为4724。但它仍然没有显示完整的QuerySMS无法打印出完整的文本长度。我记得有一个最大长度,但我不记得了。要打印完整的查询,您需要执行substring并一次打印4000。但是您的查询执行了吗?该查询工作正常。现在我创建两个NVarcharMAX变量,并使用sp_executesql执行这些变量。它成功执行,记录被插入到我的表中。我只是试着在单个变量上只执行一次。它是k@Liamneesan那么请接受这个回答。这就是如此设计的工作原理;当提问者标记一个答案,以便其他人可以找到答案时,这会有所帮助。@SMor对不起,没有人告诉我的问题出在哪里,他们只是给了我另一种解决方法。我的问题怎么了?。。。甚至我也找到了另一种方法,并像他们发布的那样成功地执行了它。