如何从变量运行超过8000个字符的SQL语句?

Rac*_*cha 20 sql t-sql sql-server varchar sql-server-2008

我可以使用以下代码进行微小的查询:

DECLARE @sql VARCHAR(8000)
SET @sql = 'SELECT * FROM myTable'
Exec @sql
Run Code Online (Sandbox Code Playgroud)

上面的方法对于维护大量代码非常有用,特别是当我们需要进行一次更改并将它们反映到任何地方时.

我的问题是我想要提供给@sql变量的查询(它只有一个查询)使用超过25个表连接,其中一些在临时表变量上,包含复杂的操作,因此长度超过8000个字符.

我希望使用TEXT数据类型来存储此查询,但MSDN显示一条警告消息,Microsoft正计划从其下一版本中删除Text,NText和Image数据类型.我希望我的代码也能在未来运行.

我想将这个查询存储在一个单独的文件中,但由于它使用表变量和其他特定于过程的参数的连接,我怀疑这是否可行.

请告诉我一个将大型查询存储到变量中并在过程中多次执行的方法.

Mik*_*Vee 24

问题在于隐式转换.

如果你有连接的Unicode/nChar/nVarChar值,那么SQL Server将隐式地将你的字符串转换为VarChar(8000),遗憾的是它太愚蠢了,以至于它不会截断你的字符串,甚至会给你一个警告数据已被删除截断了那件事!

当连接长字符串(或者你感觉可能很长的字符串)时,总是将字符串构建与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赋值,但是根据上面的解决方案,这是不必要的.

对于那些最多达到4000个字符的人来说,可能是因为你有Unicode所以它被隐式转换为nVarChar(4000).

解释:
幕后发生的事情是,即使您指定的变量使用(MAX),SQL Server也会评估您首先分配的值的右侧和默认为nVarChar(4000)或VarChar(8000)(取决于您连接的内容).完成后计算出值(并在为您截断后),然后将其转换为(MAX)时将其分配给您变量,但到那时为时已晚.


And*_*oni 16

如果您使用的是SQL Server 2008或更高版本,则可以使用VARCHAR(MAX)

DECLARE @sql VARCHAR(MAX)
Run Code Online (Sandbox Code Playgroud)


Xti*_*n11 6

DECLARE @sql VARCHAR(max)
SET @sql = 'SELECT * FROM myTable'
Exec @sql
Run Code Online (Sandbox Code Playgroud)

注意:

Print(@sql)
Run Code Online (Sandbox Code Playgroud)

只显示前8000个字符!


Thi*_* Oo 5

使用

EXEC
(
  '
   --your sql script here
  '
)
Run Code Online (Sandbox Code Playgroud)