SQL Server 2012:动态SQL限制(> 4000个字符)(拆分)

时间:2017-12-04 09:14:42

标签: sql-server sql-server-2012

我在存储过程中有这个动态SQL:

Scenario: Create User
Given path 'user'
    And request read('user.json');
    When method post
    Then status 200
    And def user_id = response.userId

Scenario: Test A
   Given path 'user/' + user_id <- Received javascript error here
   ...

Scenario: Test B
   Given path 'user/' + user_id <- Received javascript error here
   ...

Scenario: Test A
   Given path 'user/' + user_id <- Received javascript error here
   ...

Declare @template nvarchar(max) Declare @publishdetails nvarchar(max) set @publishdetails= ',B.[PublishedBy]=suser_name(), B.[PublishedDate]=GETDATE() ' set @template='if NOT EXISTS(select * from ' +@DestinationDB+ '.[CLs] where id='+ str(@slid)+') insert into ' +@DestinationDB+ '.CLs (id,slid,slversion) VALUES ( '+ str(@id)+','+ str(@slid)+','+str(@slversion)+') update B set B.[Clientid]=A.clientid, --......... B.[CreatedDate] = A.CreatedDate, B.[ModifiedDate] = A.ModifiedDate, B.[CreatedBy] = A.CreatedBy, B.[ModifiedBy] = A.ModifiedBy '+@publishdetails+ --Added publishdetails 'FROM ' + @SourceDB + '.[CLs] as A, '+ @DestinationDB+ '.[CLs] as B where A.slversion = '+ str(@slversion)+' and A.id='+str(@slid) + 'B.slversion = '+ str(@slversion)+' and B.id='+str(@slid) print 'template is: ' + @template exec sp_Executesql @template 正在执行时,它会失败。因为exec sp_Executesql @template是&gt; 4000个字符并被截断。如何将其拆分并以正确的方式执行?

2 个答案:

答案 0 :(得分:1)

您无需将文本拆分为多个部分。您确实需要确保在concatenating strings时不会发生截断:

  

如果字符串串联的结果超出了8,000字节的限制,则结果将被截断。但是,如果连接的字符串中至少有一个是大值类型,则不会发生截断。

因此,请确保第一个串联使用大值类型(因此产生一个大值类型作为结果),并且每个后续串联都应该从截断中保存:

set @template=CONVERT(nvarchar(max),'if NOT EXISTS(select * from ' ) + @DestinationDB + ...

(通过这种方式,您无需在任何地方处插入转化

这会产生错误:

declare @t nvarchar(max)

set @t = 'select LEN(''' + REPLICATE('A',3000) + REPLICATE('B',3000) + REPLICATE('C',3000) + ''')'

exec sp_executesql @t

这会产生结果9000:

declare @t nvarchar(max)

set @t = CONVERT(nvarchar(max),'select LEN(''') + REPLICATE('A',3000) + REPLICATE('B',3000) + REPLICATE('C',3000) + ''')'

exec sp_executesql @t

答案 1 :(得分:0)

我建议使用这种方法:

Declare @template nvarchar(max) = N''
set @template = @template +N'.... -- Or SELECT instead of SET

<强>更新#1

我在测试数据库上运行这个简单的查询:

DECLARE @query nvarchar(max) = N'',
        @i int = 1

WHILE 1000 > @i
BEGIN
    SET @query = @query + N'SELECT @@version;'
    SET @i = @i+1
END

SELECT LEN (@query)

EXEC sp_executesql @query

我的批次长度为16983个字符。并且执行顺利 - 没有截断。我想问题出在@SourceDB + '.[CLs]@DestinationDB+ '.[CLs]表内。在那里你有数据截断。

尝试PRINT您的查询并手动运行。