0

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 
4

1 に答える 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
    ';

@XMLReceiverID を必要とするステートメントで @query2 を再割り当てしていますが、変数は新しい @query2 割り当てに対して宣言されていません。同じことが @query 4 にも当てはまります。2 つの変数 @XML、@XMLReceiverId は、@Query1 と同じスコープにはありません。

基本的に、すべてのステートメントを 1 つの変数に連結するか、それらを 1 つの実行に結合する必要があります。

于 2013-06-26T13:54:47.713 に答える