动态插入循环

时间:2015-09-03 11:41:13

标签: sql-server

据我了解,以下代码:

scope :never_contacted, -> { joins("LEFT JOIN logs ON logs.user_id = users.id").where("logs.id IS NULL") } 

应打印:

declare @csvnmbr nvarchar(3)
declare @sql nvarchar(400)
set @csvnmbr = 1
set @sql = 'BULK INSERT #tablename FROM ''C:\TEMP\'+@csvnmbr+'.csv''
            WITH (FIELDTERMINATOR = '','')'
while @csvnmbr < 4
begin
print @sql
set @csvnmbr = @csvnmbr + 1
end
GO

但它没有打印出来:

BULK INSERT #tablename FROM 'C:\TEMP\1.csv' WITH (FIELDTERMINATOR = ',')

BULK INSERT #tablename FROM 'C:\TEMP\2.csv' WITH (FIELDTERMINATOR = ',')

BULK INSERT #tablename FROM 'C:\TEMP\3.csv' WITH (FIELDTERMINATOR = ',')

有没有人知道为什么循环不会打印数字序列而只是坚持第一个csv号呢?

如果我这样做:

BULK INSERT #tablename FROM 'C:\TEMP\1.csv' WITH (FIELDTERMINATOR = ',')

BULK INSERT #tablename FROM 'C:\TEMP\1.csv' WITH (FIELDTERMINATOR = ',')

BULK INSERT #tablename FROM 'C:\TEMP\1.csv' WITH (FIELDTERMINATOR = ',')

没有明显需要在循环中编写@sql。知道为什么@sql语句是动态的,这意味着它每次都需要重置吗?

3 个答案:

答案 0 :(得分:1)

因为它在循环开始之前设置了一次。您需要在循环内设置@sql

DECLARE @csvnmbr  INT = 1
        ,@sql     NVARCHAR(MAX);

WHILE @csvnmbr < 4
BEGIN
   SET @sql = N'BULK INSERT #tablename FROM ''C:\TEMP\'' +
               CAST(@csvnmbr AS NVARCHAR(10)) + 
               '.csv'' WITH (FIELDTERMINATOR = '','')';
   PRINT @sql;
   SET @csvnmbr += 1;
END

关于你的问题为什么它需要内循环:

declare @csvnmbr nvarchar(3)
declare @sql nvarchar(400)
set @csvnmbr = 1

/* At this point @sql if fixed string, during concatenation @csvnmbr was
   replaced by its actual value */
set @sql = 'BULK INSERT #tablename FROM ''C:\TEMP\'+@csvnmbr+'.csv''
            WITH (FIELDTERMINATOR = '','')'


while @csvnmbr < 4
begin
print @sql  /* Here sql will be always the same you need to set it again */
set @csvnmbr = @csvnmbr + 1
end

您要实现的是通过引用传递字符串。你可以像这样模仿它:

DECLARE @csvnmbr NVARCHAR(3) = '1'
        ,@sql NVARCHAR(MAX);

SET @sql = 
 N'BULK INSERT #tablename FROM ''C:\TEMP\@csvnmbr.csv'' WITH (FIELDTERMINATOR = '','')';

WHILE @csvnmbr < 4
BEGIN
   /* Warning!!! This will execute code in @sql*/
   EXEC [dbo].[sp_executesql]
           @sql,
           N'@csvnmbr nvarchar(3)',
           @cvnmbr;                  /* Will substitute @csvnmbr with passed value */

   SET @csvnmbr += 1;
END

答案 1 :(得分:0)

将你的陈述保留在while循环中

declare @csvnmbr nvarchar(3)
declare @sql nvarchar(400)
set @csvnmbr = 1

while @csvnmbr < 4
begin
 set @sql = 'BULK INSERT #tablename FROM ''C:\TEMP\'+@csvnmbr+'.csv''
            WITH (FIELDTERMINATOR = '','')'
print @sql
set @csvnmbr = @csvnmbr + 1
end
GO

while循环迭代发生在while循环条件begin和end blocks之间。

WHILE (Some Condition)   --<-- first the condition is checked
  BEGIN
                         --<-- if the while condition is evaluated to true
                            -- code between the BEGIN and END is executed
       -- it keeps getting executing until while condition returns false
  END

答案 2 :(得分:0)

你需要在每次迭代中填充@sql:

DECLARE @csvnmbr NVARCHAR(3);
DECLARE @sql NVARCHAR(400);
SET @csvnmbr = 1;

SET @sql = 'BULK INSERT #tablename FROM ''C:\TEMP\' + @csvnmbr + '.csv''
        WITH (FIELDTERMINATOR = '','')';

WHILE @csvnmbr < 4

BEGIN

    PRINT @sql;

    SET @csvnmbr = @csvnmbr + 1;

SET @sql = 'BULK INSERT #tablename FROM ''C:\TEMP\' + @csvnmbr + '.csv''
         WITH (FIELDTERMINATOR = '','')';    

END;

GO