How to create dynamic SQL queries inside CURSOR

2019-08-11 03:08发布

问题:

I have to dynamically create a query inside cursor

DECLARE @id VARCHAR(10)

declare @loc varchar(25)
set @loc = '/MainItem/SubItem';

declare @query varchar(max)     

DECLARE myCursor CURSOR LOCAL FAST_FORWARD FOR
    SELECT * FROM @tempcolumnname

OPEN myCursor
FETCH NEXT FROM myCursor INTO @id

WHILE @@FETCH_STATUS = 0 
BEGIN
    set @query = 'SELECT * FROM OPENXML(@hdoc, '+@loc+', 3) WITH (code_db_key int)'
    exec (@query)    

    FETCH NEXT FROM myCursor INTO @id
END

but executing this throws an exception

Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "@hdoc"

Msg 319, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'.

If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement
must be terminated with a semicolon.`

But when I am executing the same query outside the cursor, it is working fine.

回答1:

In cursor you have to again execute your xml file , with xml output declaration.

DECLARE @id VARCHAR(25)

declare @loc varchar(25)
set @loc = '/MainItem/SubItem';

declare @query varchar(max) 

DECLARE myCursor CURSOR LOCAL FAST_FORWARD FOR
     SELECT * FROM @tempcolumnname

OPEN myCursor
FETCH NEXT FROM myCursor INTO @id

WHILE @@FETCH_STATUS = 0 
BEGIN
    set @query = 'DECLARE @hdoc INT;           
    EXEC sp_xml_preparedocument @hdoc OUTPUT,'''+ @info+'''
        Select Statement
        Insert Statement exec (@query)      

    FETCH NEXT FROM myCursor INTO @id       
END

CLOSE myCursor
DEALLOCATE myCursor


回答2:

Try this :

DECLARE @ParmDefinition nvarchar(500);

/* Build the SQL string one time.*/
set @query = 
'SELECT * FROM OPENXML(@Temphdoc, '''+@loc+''', 3) WITH (code_db_key int)';
SET @ParmDefinition = N'@Temphdoc varchar(1000)';

/* This can be in cursor loop */

EXECUTE sp_executesql @query, @ParmDefinition,
                      @Temphdoc = @hdoc;


回答3:

Change

set @query = 'SELECT * FROM OPENXML(@hdoc, '+@loc+', 3) WITH (code_db_key int)'

to

set @query = 'SELECT * FROM OPENXML(@hdoc, '+@loc+', 3) WITH (code_db_key int);'

--

Ok, try this,

set @query = CONCAT('SELECT * FROM OPENXML(@hdoc,',+@loc+,', 3) WITH (code_db_key int);')