Подтвердить что ты не робот

Массовая вставка с использованием хранимой процедуры

У меня есть запрос, который работает нормально:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)

но теперь я хочу создать для него хранимую процедуру.

Я написал ниже код, чтобы сделать его хранимую процедуру:

create proc dbo.InsertZipCode
@filepath varchar(500)='e:\5-digit Commercial.csv'
as
begin
BULK INSERT ZIPCodes 
FROM  @filepath 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end

но его ошибка:

Msg 102, уровень 15, состояние 1, процедура InsertZipCode, строка 6 Неправильный синтаксис рядом с '@filepath'.

Msg 319, уровень 15, состояние 1, процедура InsertZipCode, строка 7 Неправильный синтаксис рядом с ключевым словом 'with'. Если это утверждение является общей таблицей выражение, предложение xmlnamespaces или предложение контекста контекста изменения, предыдущий оператор должен быть прерван с точкой с запятой.

Скажите, пожалуйста, что я делаю неправильно и что могу сделать, чтобы он работал в хранимой процедуре.

Спасибо

4b9b3361

Ответ 1

В коде хранимой процедуры нет ничего плохого: точка BULK INSERT не может принимать имя файла в качестве переменной.

Это работает:

BULK INSERT ZIPCodes 
FROM  'e:\5-digit Commercial.csv' 
WITH 

но это никогда не срабатывает - в сохраненной proc или нет:

DECLARE @filename VARCHAR(255)
SET @filename = 'e:\5-digit Commercial.csv' 

BULK INSERT ZIPCodes 
FROM @filename
WITH 

Таким образом, вы просто не можете сделать это таким образом, к сожалению. Вы можете подумать о создании своего оператора BULK INSERT в виде строки (с фиксированным именем файла), а затем выполнить ее как динамический SQL, но я не вижу другого решения.

DECLARE @filepath nvarchar(500)
SET @filepath = N'e:\5-digit Commercial.csv'

DECLARE @bulkinsert NVARCHAR(2000)

SET @bulkinsert = 
       N'BULK INSERT ZIPCodes FROM ''' + 
       @filepath + 
       N''' WITH (FIRSTROW = 2, FIELDTERMINATOR = '','', ROWTERMINATOR = ''\n'')'

EXEC sp_executesql @bulkinsert

Ответ 2

Вы просто попробуйте, я думаю, вам нужно загрузить этот CSV файл прямо на диск "E". Для этого вам нужно иметь права администратора, я думаю, или спросить кого-то, кто находится в администрировании базы данных.

create procedure dbo.InsertZipCode
AS
BEGIN
SET NOCOUNT ON;
 BULK
   INSERT ZIPCodes from 'e:\5-digit Commercial.csv'
WITH
(
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n'
)
END

Ответ 3

Существует альтернатива динамическому SQL, если у вас есть доступ к SQLCmd exe.

Утилита SqlCmd позволяет передавать переменные замены строки с помощью аргумента -v.

Вы можете использовать переменную шаблона с именем "путь к файлу", который будет заменен при выполнении сценария через cmdline.

Сценарий SQL будет выглядеть так:

BULK INSERT ZIPCodes 
FROM  '$(filepath)' 
WITH 
( 
     FIRSTROW = 2 ,
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
)
end

Затем вы выполнили бы скрипт из командной строки, используя следующее:

sqlcmd -b -S SERVER\INSTANCEHERE -E -i "PATH\FILENAMEHERE.Sql" -v FilePath = "e:\5-digit Commercial.csv" -s "|"

Важной частью примера является аргумент -v:

-v FilePath = "e:\5-digit Commercial.csv"