如何执行长动态查询(大于4000个)字符-再次

Ron*_*n_S 2 sql-server dynamic exec sql-server-2008-r2

注意:我正在SQL Server 2008 R2下运行...

我花了一些时间阅读本网站以及其他网站上数十篇有关如何执行动态SQL(查询超过4000个字符)的文章。我已经尝试了十多种建议的解决方案。共识似乎是将查询分为4000个字符的变量,然后执行以下操作:

EXEC (@SQLQuery1 + @SQLQuery2)
Run Code Online (Sandbox Code Playgroud)

这对我不起作用-查询在@ SQLQuery1的末尾被截断。

现在,我已经看到了人们如何通过使用REPLICATE一堆空格等来“强制”长查询的示例,但这是一个真正的查询-但是比这复杂得多。

我有名称为“ Company_A_ItemView”的SQL视图。

我有10家公司想要创建相同的确切视图,并使用不同的名称,例如“ Company_B_ItemView”,“ Company_C_ItemView” .. etc。

如果您提供帮助,请不要问为什么会有多个视图-只需接受我需要这样做即可,好吗?

每个公司都有自己的一组表,并且CREATE VIEW语句按名称引用了几个表。这是Brief示例,但请记住,查询的总长度约为6000个字符:

CREATE view [dbo].[Company_A_ItemView] as  
select  
WE.[Item No_],  
WE.[Location Code],   
    LOC.[Bin Number],  
[..more fields, etc.]  
from  
[Company_A_Warehouse_Entry] WE  
left join  
[Company_A_Location] LOC  
Run Code Online (Sandbox Code Playgroud)

...你明白了

所以,我目前正在做的是:

一种。将CREATE VIEW语句的内容拉入2个声明的变量中,例如

Set @SQLQuery1 = (select text 
                  from syscomments 
                  where ID = 1382894081 and colid = 1)  
Set @SQLQuery2 = (select 
                  from syscomments 
                  where ID = 1382894081 and colid = 2)
Run Code Online (Sandbox Code Playgroud)

请注意,这就是SQL存储长定义的方式-创建视图时,它将文本存储到多个syscomments记录中。在我的情况下,视图被拆分为第一个系统记录记录中的3591个字符的文本块,其余文本在第二个记录中。我不知道为什么SQL在syscomment字段中不使用所有4000个字符。一句话就打断了这个陈述。

请注意,在我所有的示例中,所有@SQLQueryxxx变量都声明为varchar(max)。我也尝试过将它们声明为nvarchar(max)和varchar(8000)以及nvarchar(8000),结果相同。

b。然后,对“ Company_A”执行“搜索并替换”,然后将其替换为“ Company_B”。在下面的代码中,变量“ @CompanyID”首先设置为“ Company_B”:

SET @SQLQueryNew1 = @SQLQuery1   
SET @SQLQueryNew1 = REPLACE(@SQLQueryNew1, 'Company_A', @CompanyID)  
SET @SQLQueryNew2  = @SQLQuery2   
SET @SQLQueryNew2 = REPLACE(@SQLQueryNew2, 'Company_A',@CompanyID)
Run Code Online (Sandbox Code Playgroud)

C。然后,我尝试:

EXEC (@SQLQueryNew1 + @SQLQueryNew2)
Run Code Online (Sandbox Code Playgroud)

返回的消息表明它正在尝试执行在@ SQLQueryNew1结尾处被截断的语句,例如查询文本的80%(大约)。

我试过将最终结果转换成新的varchar(max)和nvarchar(max)-没运气我试过将原始查询转换成新的varchar(max)和nvarchar(max)-没有运气

我已经查看了检索原始CREATE VIEW语句的结果,这很好。

我尝试了各种其他方法来检索原始的CREATE VIEW语句,例如:

Set @SQLQuery1 = (select VIEW_DEFINITION) 
                  FROM [MY_DATABASE].[INFORMATION_SCHEMA].[VIEWS] 
                  where TABLE_NAME = 'Company_A_ItemView')`
Run Code Online (Sandbox Code Playgroud)

这个仅返回CREATE VIEW的前4000个字符

Set @SQLQuery1 = (SELECT (OBJECT_DEFINITION(@ObjectID))
Run Code Online (Sandbox Code Playgroud)

如果我做一个

SELECT LEN(OBJECT_DEFINITION(@ObjectID))
Run Code Online (Sandbox Code Playgroud)

它返回正确的查询长度(例如5191),但是如果我查看@ SQLQuery1或尝试

EXEC(@SQLQuery1), the statement is still truncated.
Run Code Online (Sandbox Code Playgroud)

C。有一些引用指出,由于我在检索查询后处理查询的文本,因此结果变量被截断为4000个字符。我尝试替换时尝试使用CAST'ing结果,例如

SET @SQLQueryNew1 = SELECT (CAST(REPLACE(@SQLQueryNew1, 
                                 'Company_A', 
                                 @CompanyID) AS varchar(max))
Run Code Online (Sandbox Code Playgroud)

结果相同。

我知道还有其他方法,例如创建用于创建视图的存储过程。但是视图正在开发中并且有些“不断变化”,因此将CREATE VIEW的文本放在存储的proc中很麻烦。我的目标是能够获取Company_A的视图并准确地复制它-多次,除了引用Company_B的视图名称和表名称,Company_C的视图名称和表名称等。

我想知道是否有人对这种长SQL“ CREATE VIEW”语句进行了这种类型的处理并尝试执行它。

RBa*_*ung 5

只需使用VARCHAR(MAX)NVARCHAR(MAX)即可。他们适合EXEC(string)


仅供参考

请注意,这就是SQL存储长定义的方式-创建视图时,它将文本存储到多个syscomments记录中。

这是不正确的。这是如何使用将SQL Server 2000上完成,因为SQL Server 2005和更高将它们保存为NVARCHAR(MAX)在单个条目sys.sql_modules

syscomments仍然存在,但仅出于兼容性目的而保留为只读。


因此,您需要做的就是更改您的@ SQLQuery1,2等。变量复制到单个NVARCHAR(MAX)变量,然后从sys.sql_modules表的[definition]列中提取View代码。

请注意,您应该谨慎对待字符串操作,因为如果某些函数的所有输入参数都不都是(N)VARCHAR(MAX),则某些函数会还原为(N)VARCHAR(4000)输出。(对不起,我不知道是哪一个,但是REPLACE()可能是其中之一)。实际上,这可能是导致测试混乱的原因。