2017-01-13 2 views
2

Я адаптировал запрос, найденный онлайн, для массового импорта CSV-файлов в SQL-сервер. Однако у моих CSV есть запасной канал в нижней части, поэтому я добавил счетчик для количества строк в файле, а затем установил параметр LASTROW в BULK INSERT.Ошибка SQL-сервера: Должен объявить скалярную переменную «@lastrow»

Однако, поскольку я зацикливаю BULK INSERT, мне нужно передать имя файла в счетчик строк. Но я получаю сообщение об ошибке «Должен объявить скалярную переменную« @lastrow », когда выполняется @filllastrow. Может ли кто-нибудь помочь?

Благодаря

Роб

 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 

ответ

0

Использование 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 
+0

Спасибо. Я удалил запасной кронштейн после «MAXERRORS = 10» как «а затем выдал ошибку Msg 102, уровень 15, состояние 1, строка 5 Неверный синтаксис рядом с« @lastrow ». –

0

Put 'объявить @lastrow Int' в строке @sql, удалите преобразования типов и запустить оба SQL заявления вместе, чтобы сохранить @lastrow ток. Запустите BULK INSERT в функции EXEC, чтобы передать ему параметр. @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 
+0

Спасибо. Я пробовал это и получаю сообщение об ошибке, объявляющее @lastrow ....), не является допустимым идентификатором. Я думаю, проблема заключается в том, что объемная вставка не может принимать переменную как параметр LASTROW. –

+0

@RobShaw_UK Я обновился, чтобы объявить последнюю в качестве целого числа. Просто обновил ее, чтобы исправить опечатку. – cloudsafe

+0

Спасибо, но я все равно получаю ту же ошибку. Если я запускаю текст из print @sql на свой собственный, я получаю «Неправильный синтаксис рядом с« @lastrow ».» –

Смежные вопросы