【问题标题】:SQL server error: Must declare the scalar variable "@lastrow"SQL 服务器错误:必须声明标量变量“@lastrow”
【发布时间】:2017-01-13 09:23:21
【问题描述】:

我已经修改了一个在线查询,将 CSV 文件批量导入 SQL 服务器。但是,我的 CSV 在底部有一个备用换行符,因此我为文件中的行数添加了一个计数器,然后在 BULK INSERT 中设置了 LASTROW 参数。

但是,因为我正在循环 BULK INSERT,所以我需要将文件名传递给行计数器。但是当@filllastrow 执行时,我收到错误“必须声明标量变量“@lastrow””。有人可以帮忙吗?

谢谢

罗伯

        declare @filename varchar(255),
        @path     varchar(255),
        @sql      varchar(8000),
        @filllastrow      varchar(8000),
        @cmd      varchar(1000)

declare c1 cursor for SELECT WHICHPATH,WHICHFILE FROM ALLFILENAMES where WHICHFILE like '%.csv%'
open c1
fetch next from c1 into @path,@filename
While @@fetch_status <> -1
 begin
  declare @lastrow varchar(10)
  set  @filllastrow = 'set @lastrow = convert(varchar(10),(SELECT count(*) FROM OPENROWSET( BULK '''+ @path + @filename+''', FORMATFILE = ''E:\ereferrals\MyFormat_Counting.fmt'', MAXERRORS=10) AS a ) - 1)'
  print @filllastrow
  exec (@filllastrow)

 set @sql = 'BULK INSERT eref FROM ''' + @path + @filename + ''' '
       + '     WITH ( 
               FIELDTERMINATOR = '','', 
               ROWTERMINATOR = ''0x0A'', 
               FIRSTROW = 2 ,
               LASTROW = '+convert(varchar,@lastrow)+',
               ERRORFILE = ''e:\ereferrals\probs.log''
            ) '
print @sql
EXECUTE @sql
fetch next from c1 into @path,@filename
end
close c1
deallocate c1

【问题讨论】:

    标签: sql-server bulkinsert declare


    【解决方案1】:

    使用sp_executesql 并将@lastrow 参数定义为输出参数。

    试试这样的……

    declare @filename       nvarchar(255)
           ,@path           nvarchar(255)
           ,@sql            nvarchar(MAX)  --<-- Correct datatype
           ,@filllastrow    nvarchar(MAX)  --<-- Correct datatype
           ,@cmd            nvarchar(1000)
    
    
    declare c1 cursor for 
    SELECT WHICHPATH , WHICHFILE 
    FROM ALLFILENAMES 
    where WHICHFILE like '%.csv%'
    
    open c1
    
    fetch next from c1 into @path,@filename
    
    
    While @@fetch_status <> -1
     begin
      declare @lastrow  INT;
    
      set  @filllastrow = 'SELECT @lastrow = convert(varchar(10),  ISNULL(count(*),2) -1)
                           FROM OPENROWSET( BULK '''+ @path + @filename+'''
                                          , FORMATFILE = ''E:\ereferrals\MyFormat_Counting.fmt''
                                          , MAXERRORS=10) AS a )'
    
    
         Exec sp_executesql @filllastrow
                           ,N'@lastrow INT OUTPUT'   --<-- Output parameter
                           ,@lastrow OUTPUT                                 
    
     set @sql = 'BULK INSERT eref FROM ''' + @path + @filename + ''' '
           + '     WITH ( 
                   FIELDTERMINATOR = '','', 
                   ROWTERMINATOR = ''0x0A'', 
                   FIRSTROW = 2 ,
                   LASTROW = @lastrow,   
                   ERRORFILE = ''e:\ereferrals\probs.log''
                ) '
    
       Exec sp_executesql @sql
                         ,N'@lastrow INT'
                         ,@lastrow
    
    fetch next from c1 into @path,@filename
    end
    close c1
    deallocate c1
    

    【讨论】:

    • 谢谢。我删除了 "MAXERRORS=10) as a" 之后的备用括号,然后它给出了错误 Msg 102, Level 15, State 1, Line 5 Incorrect syntax near '@lastrow'。
    【解决方案2】:

    将'declare @lastrow int' 放在@sql 字符串中,删除类型转换并同时运行两个sql 语句以保持@lastrow 最新。在 EXEC 函数中运行 BULK INSERT 以将参数传递给它。不需要@Filllastrow:

    declare @filename varchar(255),
            @path     varchar(255),
            @sql      varchar(8000),
            @cmd      varchar(1000)
    
    declare c1 cursor for SELECT WHICHPATH,WHICHFILE FROM ALLFILENAMES
                            where WHICHFILE like '%.csv%'
    open c1
    fetch next from c1 into @path,@filename
    While @@fetch_status <> -1
     begin
      set  @sql = ' declare @lastrow as int set @lastrow =
           (SELECT count(*) 
           FROM OPENROWSET( BULK '''+ @path + @filename+''', FORMATFILE =
           ''E:\ereferrals\MyFormat_Counting.fmt'', MAXERRORS=10) AS a ) - 1 
           EXEC(''BULK INSERT eref FROM ''''' + @path + @filename + ''''' '
           + '     WITH ( 
                   FIELDTERMINATOR = '''','''', 
                   ROWTERMINATOR = ''''0x0A'''', 
                   FIRSTROW = 2 ,
                   LASTROW = '' + @lastrow + '',
                   ERRORFILE = ''''e:\ereferrals\probs.log''''
                ) '
    print @sql
    EXECUTE @sql
    fetch next from c1 into @path,@filename
    end
    close c1
    deallocate c1
    

    【讨论】:

    • 谢谢。我试过了,并得到错误消息'declare @lastrow ....)'不是有效的标识符。我认为问题在于批量插入不能接受变量作为 LASTROW 参数。
    • @RobShaw_UK 我已更新以将 lastrow 声明为整数。--刚刚再次更新以更正错字。
    • 谢谢,但我仍然遇到同样的错误。如果我自己运行 print @sql 中的文本,我会得到“'@lastrow' 附近的语法不正确。”
    • @RobShaw_UK BULK INSERT 无法传递参数,所以我修改了代码以动态运行它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多