Массовая вставка с использованием хранимой процедуры
У меня есть запрос, который работает нормально:
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 или предложение контекста контекста изменения, предыдущий оператор должен быть прерван с точкой с запятой.
Скажите, пожалуйста, что я делаю неправильно и что могу сделать, чтобы он работал в хранимой процедуре.
Спасибо
Ответы
Ответ 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"