【问题标题】:Executing multiple query strings using a variable declared at first one使用第一个声明的变量执行多个查询字符串
【发布时间】:2019-07-22 20:48:32
【问题描述】:

我需要执行一个基于 xml 变量的长动态查询字符串,然后我需要将字符串拆分为多个 varchar 变量,每个变量都包含游标内表中更新的一部分。

我将发布部分查询:

DECLARE @QUERY1 VARCHAR(8000);
DECLARE @QUERY2 VARCHAR(8000);
DECLARE @QUERY3 VARCHAR(8000);
DECLARE @QUERY4 VARCHAR(8000);

DECLARE @cols AS VARCHAR(8000);

DECLARE @begin INT
DECLARE @totalid INT
DECLARE @groupsize INT
SET @groupsize = 0
SELECT @totalid = MAX(IntegrationId) FROM Integration
set @QUERY1 = N'
BEGIN TRANSACTION
DECLARE @xml XML 
DECLARE @XMLReceiverID int
DECLARE XMLRowItem CURSOR FOR
SELECT XMLReceiverID,XMLContent FROM XMLReceiver WHERE FlagImportData = 0 and Typology = ''XXXX''
OPEN XMLRowItem
FETCH XMLRowItem INTO @XMLReceiverID,@xml
WHILE @@Fetch_Status = 0

BEGIN
';
set @QUERY2 = N'
INSERT INTO IntegrationData (XmlReceiverID) 
';
set @QUERY3 = N'
SELECT @XMLReceiverID
';      
--PRINT @QUERY1 + @QUERY2 + @QUERY3
EXEC (@QUERY1 + @QUERY2 + @QUERY3)      
WHILE @groupsize <= @totalid
BEGIN
SET @begin = @groupsize
SET @groupsize = @groupsize + 10
select @cols = 
(select STUFF((SELECT distinct ',',  QUOTENAME(FieldName), ' = ' , CASE WHEN XMLPath IS NULL THEN 'NULL' ELSE '(SELECT TOP 1 c.value(''(' + (REVERSE(LEFT(REVERSE(XMLPath), CHARINDEX('/', REVERSE(XMLPath)) - 1)))  + ')[1]'',''VARCHAR(50)'') FROM  @xml.nodes(''' + REPLACE(XMLPath,'/' + REVERSE(LEFT(REVERSE(XMLPath), CHARINDEX('/', REVERSE(XMLPath)) - 1)), '') + ''') t(c)) ' END 
from IntegracaoOpcaoLayout
where FlagIntegration = 1 
AND XMLPath IS NOT NULL
AND IntegrationId > @begin
AND IntegrationId <= @groupsize
order by QUOTENAME(FieldName) asc

FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')  ,1,1,''))

set @QUERY2 = N'
UPDATE IntegrationData SET ' + @cols + ' WHERE XmlReceiverID = @XMLReceiverID
';
EXEC (@QUERY2)
--PRINT @QUERY2
END 
set @QUERY4 = N'    
UPDATE XMLReceiver SET FlagIntegration = 1 WHERE XMLReceiverID = @XMLReceiverID AND FlagImportData = 0
FETCH NEXT FROM XMLRowItem into @XMLReceiverID,@xml
END
PRINT @XMLReceiverID
CLOSE XMLRowItem

DEALLOCATE XMLRowItem
COMMIT TRANSACTION
';
EXEC (@QUERY4)
--PRINT @QUERY4

如果我运行这段代码打印查询字符串并执行它一切正常!

但是如果我正常运行,我会得到下面的错误(关于也没有声明在第一个 exec 语句中声明的变量):

Msg 102, Level 15, State 1, Line 15
Incorrect syntax near '@XMLReceiverID'.
Msg 137, Level 15, State 2, Line 2
Must declare the scalar variable "@xml".

有没有人可以解决或建议?

这是打印的查询:

BEGIN TRANSACTION
DECLARE @xml XML 
DECLARE @XMLReceiverID int
DECLARE XMLRowItem CURSOR FOR
SELECT XMLReceiverID,XMLContent FROM XMLReceiver WHERE FlagImportData = 0 and Typology = 'XXXX'
OPEN XMLRowItem
FETCH XMLRowItem INTO @XMLReceiverID,@xml
WHILE @@Fetch_Status = 0

BEGIN

INSERT INTO IntegrationData (XmlReceiverID) 

SELECT @XMLReceiverID

UPDATE IntegrationData SET [Field1] = (SELECT TOP 1 c.value('(test1)[1]','VARCHAR(50)') FROM  @xml.nodes('/xmlPath/test1') t(c)) ,
[Field2] = (SELECT TOP 1 c.value('(test2)[1]','VARCHAR(50)') FROM  @xml.nodes('/xmlPath/test2') t(c)) ,
[Field3] = (SELECT TOP 1 c.value('(test3)[1]','VARCHAR(50)') FROM  @xml.nodes('/xmlPath/test3') t(c)) 
UPDATE XMLReceiver SET FlagImportData = 1 WHERE XMLReceiverID = @XMLReceiverID AND FlagImportData = 0
FETCH NEXT FROM XMLRowItem into @XMLReceiverID,@xml
END
PRINT @XMLReceiverID
CLOSE XMLRowItem

DEALLOCATE XMLRowItem
COMMIT 

【问题讨论】:

  • 您从打印中得到什么输出?
  • 请把表格DDL、样本数据和预期结果贴出来,否则我们只能猜测您实际需要什么。如果你真的觉得你的问题只能通过使用 dynamc T-SQL 来解决,请阅读以下由 Erland Sommarskog 撰写的关于该主题的文章:sommarskog.se/dynamic_sql.htmlML
  • 我发布了@bastos.sergio

标签: sql sql-server-2008 tsql


【解决方案1】:

您的代码抛出错误的原因是您的所有代码都超出了范围。

这是你的问题。

 set @QUERY2 = N'
    UPDATE IntegrationData SET ' + @cols + ' WHERE XmlReceiverID = @XMLReceiverID
    ';
    EXEC (@QUERY2)
    --PRINT @QUERY2
    END 
    set @QUERY4 = N'    
    UPDATE XMLReceiver SET FlagIntegration = 1 WHERE XMLReceiverID = @XMLReceiverID AND FlagImportData = 0
    FETCH NEXT FROM XMLRowItem into @XMLReceiverID,@xml
    END
    PRINT @XMLReceiverID
    CLOSE XMLRowItem

    DEALLOCATE XMLRowItem
    COMMIT TRANSACTION
    ';

您可以看到您使用需要@XMLReceiverID 的语句重新分配@query2,但尚未为新的@query2 分配声明变量。 @query 4 也是如此。@XML、@XMLReceiverId 这两个变量与@Query1 不在同一范围内。

本质上,您需要将所有语句连接到一个变量中,或者将它们组合到一个执行中。

【讨论】:

  • 问题是由于变量的最大大小,我无法连接。查询变得超过 8000。我需要一段时间来执行多个更新,因为完整更新超过 8000
  • 不能把变量改成varchar(max)吗?
  • 您使用的是什么版本的 SQL Server?您可以改用 VARCHAR(MAX) (SQL 2005+) 吗?
  • varchar(max) 有 8000 个字符作为 maxsize
  • "varchar(max) 有 8000 个字符作为 maxsize" -- 这不是真的。它最多可容纳 2 GB 的数据。
猜你喜欢
  • 2011-04-19
  • 2021-09-26
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 2012-11-02
  • 2012-09-14
  • 1970-01-01
相关资源
最近更新 更多