Использование Dynami c SQL для массовой вставки в хранимой процедуре - PullRequest
0 голосов
/ 31 марта 2020

У меня есть приложение. NET, из которого я вызываю 2 хранимые процедуры. Одной из этих хранимых процедур является Bulk Insert, к которой я передам подходящее имя файла, имя таблицы и разделитель из приложения. NET. После некоторых исследований я обнаружил, что мне нужно будет использовать Dynami c SQL, чтобы разрешить переменные имена файлов в BULK INSERT.

Код, который я сейчас читаю:

CREATE PROCEDURE transfer_data 
    @file_path VARCHAR, @t_name VARCHAR, @delimeter VARCHAR
AS
    BULK INSERT @t_name
    FROM @file_path
    WITH (
             FIELDTERMINATOR = @delimeter,
             ROWTERMINATOR = '\n'
         );

Как мне это изменить? Другие примеры, которые я видел ( BULK INSERT с именем файла переменной ), все еще задают переменную в запросе, однако я буду передавать параметры из моего. NET App.

1 Ответ

2 голосов
/ 31 марта 2020

Вам необходимо безопасно ввести значения. Вы не можете заменить литералы переменными. Поскольку путь к файлу может быть длиннее 128 символов, я использую REPLACE вместо QUOTENAME. Я также предполагаю , что разделитель имеет длину только 1 символ:

CREATE PROCEDURE dbo.transfer_data @file_path nvarchar(255), @s_name sysname = N'dbo', @t_name sysname, @delimiter nchar(1) AS
BEGIN

    DECLARE @SQL nvarchar(MAX),
            @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

    SET @SQL = N'BULK INSERT ' + QUOTENAME(@s_name) + N'.' + QUOTENAME(@t_name) + @CRLF +
               N'FROM N''' + REPLACE(@file_path,'''','''''') + N'''' + @CRLF + 
               N'WITH (FIELDTERMINATOR = N' + QUOTENAME(@delimiter,'''') + N',' + @CRLF + 
               N'      ROWTERMINATOR = ''\n'');'

    --PRINT @SQL;
    EXEC sys.sp_executesql @SQL;
END;
...