While loop inside Dynamic SQL query

Priya Jha 866 Reputation points
2022-08-08T12:55:27.377+00:00

I have a requirement wherein inside a dynamic sql query i want to execute another dynamic query in a while loop

PFB the code for which i am facing issues, also note that parts of the code in the outer dynamic query has been removed as those are working properly, facing issues with the code that is written inside the while loop:

declare @createindex table  
(id int identity(1,1),  
indexscript varchar(max))  
  
insert into @createindex values ('Create Index Index1 on table1 (Col1)')  
insert into @createindex values ('Create Index Index2 on table1 (Col2)')  
  
select * from @createindex  
  
declare @countindex int  
declare @count int  
set @countindex = (select count(1) from @createindex)  
set @count = 1  
declare @indexscript varchar(max)  
  
DECLARE @SQL VARCHAR(max)  
SET @SQL='  
while ('+convert(varchar(12),@count)+'<='+convert(varchar(12),@countindex)+')  
begin  
  
set'+ @indexscript+' = (select indexscript from'+  @createindex+'  where id ='+ convert(varchar(12),@count)+')  
  
exec ('+@indexscript+')  
  
set'+ convert(varchar(12),@count)+'='+convert(varchar(12),@count+1)+'  
  
end'  
  
exec @SQL  

Error:
Msg 137, Level 16, State 1, Line 23
Must declare the scalar variable "@createindex".

Azure SQL Database
SQL Server
SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
12,895 questions
Transact-SQL
Transact-SQL
A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
4,563 questions
{count} votes

Accepted answer
  1. LiHong-MSFT 10,046 Reputation points
    2022-08-09T01:51:04.9+00:00

    Hi @Priya Jha
    When you EXEC with a string, the command is carried out in a new session, so variables cannot be used pass arguments or get results. However, you could create a temporary table and use this table inside the dynamic statement, like this:

    CREATE TABLE #createindex (id int identity(1,1), indexscript varchar(max));  
    INSERT INTO #createindex VALUES ('Create Index Index1 on table1 (Col1)')  
    INSERT INTO #createindex VALUES ('Create Index Index2 on table1 (Col2)')     
       
    DECLARE @SQL VARCHAR(max)  
    SET @SQL='  
     declare @countindex int  
     declare @count int  
     set @countindex = (select count(1) from #createindex)  
     set @count = 1  
     declare @indexscript varchar(max)  
      
     while (@count <=@countindex)  
     begin  
     set @indexscript = (select indexscript from #createindex where id =@count)  
     exec (@indexscript)   
     set @count =@count+1   
     end'  
    PRINT @SQL      
    EXEC (@SQL)  
    

    Best regards,
    LiHong


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our Documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Tom Phillips 17,716 Reputation points
    2022-08-08T15:28:44.423+00:00

    If you print your @alenzi you will find your error.

    You cannot pass a table variable that way. You will need to use sp_executesql and a variable to pass the contents of the table.

    1 person found this answer helpful.
    0 comments No comments

  2. Erland Sommarskog 102.3K Reputation points
    2022-08-08T21:34:31.663+00:00

    Writing complex dynamic SQL like this requires a structured approach. I am not going to explain it here, because I have already have a long article about dynamic SQL on my web site: https://www.sommarskog.se/dynamic_sql.html.

    When it comes to crafting dynamic SQL like this, there are rarely any shortcuts. That is, attempts to make shortcuts, often ends in tears, grey hairs, and eventually leads to questions like this.

    It is better to accept that dynamic SQL is an advanced feature and let it take the time it takes.

    1 person found this answer helpful.
    0 comments No comments

  3. Naomi 7,361 Reputation points
    2022-08-08T13:28:42.867+00:00

    Did you try print @alenzi to see what do you get as your final script?

    I think this complex script is unlikely to execute, but you also need exec (@alenzi ). @alenzi in parentesis.

    0 comments No comments