And*_*old 52 sql dynamic-sql sql-server-2008
所以我在MS SQL Server 2008中编写了一个存储过程.这是一个非常长的查询,我必须动态编写它,所以我创建一个名为的变量@Query并使其成为类型NVARCHAR(MAX).现在,我被告知在现代版本的SQL Server中,NVARCHAR(MAX)可以容纳一大堆数据,比最初的4000个字符最多.但是,@Query当我尝试将其打印出来时,仍会被截断为4000个字符.
DECLARE @Query NVARCHAR(max);
SET @Query = 'SELECT...' -- some of the query gets set here
SET @Query = @Query + '...' -- more query gets added on, etc.
-- later on...
PRINT LEN(@Query) -- Prints out 4273, which is correct as far as I can tell
PRINT @Query -- Truncates value to 4000 characters
EXEC sp_executesql @Query -- totally crashes due to malformed (truncated) query
Run Code Online (Sandbox Code Playgroud)
我做错了什么,或者我完全错误的做法是什么NVARCHAR(MAX)?
小智 63
问题似乎与SET语句有关.我认为表达式的大小不能超过4,000个字节.如果你要做的就是分配一个超过4,000个字符的动态生成语句,则无需对任何设置进行任何更改.你需要做的是分割你的作业.如果您的语句长度为6,000个字符,请找到逻辑断点,然后将后半部分连接到同一个变量.例如:
SET @Query = 'SELECT ....' [Up To 4,000 characters, then rest of statement as below]
SET @Query = @Query + [rest of statement]
Run Code Online (Sandbox Code Playgroud)
现在正常运行您的查询即 EXEC ( @Query )
Mik*_*Vee 60
如果您正在连接Unicode/nChar/nVarChar值,那么SQL Server将隐式地将您的字符串转换为nVarChar(4000),遗憾的是它太愚蠢了,以至于它不会截断您的字符串,甚至会给您一个警告数据已被删除截断了那件事!
当连接长字符串(或者你感觉可能很长的字符串)时,总是将字符串构建与CAST(''作为nVarChar(MAX))预连接,如下所示:
SET @Query = CAST('' as nVarChar(MAX))--Force implicit conversion to nVarChar(MAX)
+ 'SELECT...'-- some of the query gets set here
+ '...'-- more query gets added on, etc.
Run Code Online (Sandbox Code Playgroud)
想到这就是SQL Server的工作方式真是太痛苦和可怕了. :(
我知道网上的其他解决方法是说使用多个变量将你的代码分解成多个SET/SELECT赋值,但是根据上面的解决方案,这是不必要的.
对于那些最多达到8000个字符的人来说,可能是因为你没有Unicode因此被隐式转换为VarChar(8000).
说明:
幕后发生的事情是,即使您指定的变量使用(MAX),SQL Server也会评估您首先分配的值的右侧并且默认为nVarChar(4000)或VarChar(8000)(取决于你连接的内容).完成后计算出值(并在为你截断之后),然后在分配给它时将其转换为(MAX)你的变量,但到那时为时已晚.
Ric*_*iwi 12
要查看生成的动态SQL,请更改为文本模式(快捷键: Ctrl-T),然后使用SELECT
PRINT LEN(@Query) -- Prints out 4273, which is correct as far as I can tell
--SET NOCOUNT ON
SELECT @Query
Run Code Online (Sandbox Code Playgroud)
至于sp_executesql尝试这个(在文本模式下),它应该显示三个aaaaa...中间的一个是最长的'SELECT ..'添加.观察Ln... Col..右下方状态栏中的 指示器,显示第二个输出结束时的4510.
declare @n nvarchar(max)
set @n = REPLICATE(convert(nvarchar(max), 'a'), 4500)
SET @N = 'SELECT ''' + @n + ''''
print @n -- up to 4000
select @n -- up to max
exec sp_Executesql @n
Run Code Online (Sandbox Code Playgroud)
打印将 varchar(MAX) 截断为 8000,将 nvarchar(MAX) 截断为 4000 个字符。
但;
PRINT CAST(@query AS NTEXT)
Run Code Online (Sandbox Code Playgroud)
将打印整个查询。
文本结果最多只允许8192个字符.

我用这种方法
DECLARE @Query NVARCHAR(max);
set @Query = REPLICATE('A',4000)
set @Query = @Query + REPLICATE('B',4000)
set @Query = @Query + REPLICATE('C',4000)
set @Query = @Query + REPLICATE('D',4000)
select LEN(@Query)
SELECT @Query /*Won't contain any "D"s*/
SELECT @Query as [processing-instruction(x)] FOR XML PATH /*Not truncated*/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
95750 次 |
| 最近记录: |