在我的环境中,我们不允许为SQL服务帐户授予对网络共享文件夹的访问权限。
因此,我创建了一个包含所有BULK INSERT参数的相同存储过程,并将使用xp_cmdshell代理帐户,该帐户可以配置为任何需要的用户。
因此,该过程接受了另外2个参数,首先将文件复制到服务器上的本地%TEMP%文件夹中,然后在文件上应用批量插入,然后将其删除。
我希望这会有所帮助,因为别无选择。
后四个参数使您可以使用普通的BULK INSERT或在服务器%TEMP%文件夹中缓存文件的参数,以及其他一些设置。
CREATE PROCEDURE [dbo].[up_BULK_INSERT] (
-- main params
@DESTINATION_TABLE NVARCHAR(250),
@SOURCE_DATAFILE NVARCHAR(250),
-- bulk insert params
@BATCHSIZE NVARCHAR(100) = NULL,
@CHECK_CONSTRAINTS NVARCHAR(100) = NULL,
@CODEPAGE NVARCHAR(100) = NULL,
@DATAFILETYPE NVARCHAR(100) = NULL,
@DATA_SOURCE NVARCHAR(100) = NULL,
@ERRORFILE NVARCHAR(100) = NULL,
@ERRORFILE_DATA_SOURCE NVARCHAR(100) = NULL,
@FIRSTROW NVARCHAR(100) = NULL,
@FIRE_TRIGGERS NVARCHAR(100) = NULL,
@FORMATFILE_DATASOURCE NVARCHAR(100) = NULL,
@KEEPIDENTITY NVARCHAR(100) = NULL,
@KEEPNULLS NVARCHAR(100) = NULL,
@KILOBYTES_PER_BATCH NVARCHAR(100) = NULL,
@LASTROW NVARCHAR(100) = NULL,
@MAXERRORS NVARCHAR(100) = NULL,
@ORDER NVARCHAR(100) = NULL,
@ROWS_PER_BATCH NVARCHAR(100) = NULL,
@ROWTERMINATOR NVARCHAR(100) = NULL,
@TABLOCK NVARCHAR(100) = NULL,
-- bulk insert - input file format options
@FORMAT NVARCHAR(100) = NULL,
@FIELDQUOTE NVARCHAR(100) = NULL,
@FORMATFILE NVARCHAR(100) = NULL,
@FIELDTERMINATOR NVARCHAR(100) = NULL,
@MAKE_TEMP_LOCALCOPY BIT = 1,
@CLEANUP_TEMP BIT = 1,
@TRUNCATE_FIRST BIT = 0,
@DEBUG BIT = 0
) AS
BEGIN
DECLARE @strSQL_Query NVARCHAR(MAX)
DECLARE @importFile NVARCHAR(MAX) = @SOURCE_DATAFILE
IF @DESTINATION_TABLE = '' OR @SOURCE_DATAFILE = ''
BEGIN
RAISERROR (15600,-1,-1, 'up_BULK_INSERT');
END
IF @MAKE_TEMP_LOCALCOPY = 1
BEGIN
DECLARE @tempFolder NVARCHAR(MAX) = '\AppData\Local\Temp\'
DECLARE @result TABLE (Line NVARCHAR(512))
IF @DEBUG = 1 PRINT 'Getting profile fullpath: EXEC xp_cmdshell ''ECHO %USERPROFILE%'''
INSERT INTO @result EXEC xp_cmdshell 'ECHO %USERPROFILE%'
SET @tempFolder = (select top 1 * from @result where Line is not null) + @tempFolder
DECLARE @strCMDSHELL NVARCHAR(4000) = N'COPY /Y "' + @SOURCE_DATAFILE + '" "'+@tempFolder+'"'
IF @DEBUG = 1 PRINT 'Copying the file to local profile temp folder: EXEC xp_cmdshell ''' + @strCMDSHELL + ''''
EXEC xp_cmdshell @strCMDSHELL,no_output
SET @importFile = @tempFolder + RIGHT(@SOURCE_DATAFILE, CHARINDEX('\', REVERSE(@SOURCE_DATAFILE)) -1)
END
SET @strSQL_Query = 'BULK INSERT [' + @DESTINATION_TABLE + '] FROM ''' + @importFile + ''''
IF @BATCHSIZE IS NOT NULL OR
@CHECK_CONSTRAINTS IS NOT NULL OR
@CODEPAGE IS NOT NULL OR
@DATAFILETYPE IS NOT NULL OR
@DATA_SOURCE IS NOT NULL OR
@ERRORFILE IS NOT NULL OR
@ERRORFILE_DATA_SOURCE IS NOT NULL OR
@FIRSTROW IS NOT NULL OR
@FIRE_TRIGGERS IS NOT NULL OR
@FORMATFILE_DATASOURCE IS NOT NULL OR
@KEEPIDENTITY IS NOT NULL OR
@KEEPNULLS IS NOT NULL OR
@KILOBYTES_PER_BATCH IS NOT NULL OR
@LASTROW IS NOT NULL OR
@MAXERRORS IS NOT NULL OR
@ORDER IS NOT NULL OR
@ROWS_PER_BATCH IS NOT NULL OR
@ROWTERMINATOR IS NOT NULL OR
@TABLOCK IS NOT NULL OR
-- bulk insert - input file format options
@FORMAT IS NOT NULL OR
@FIELDQUOTE IS NOT NULL OR
@FORMATFILE IS NOT NULL OR
@FIELDTERMINATOR IS NOT NULL
BEGIN
--start Bulk insert conditions definition
SET @strSQL_Query = @strSQL_Query + ' WITH ( '
-- bulk insert main parameters
IF @BATCHSIZE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'BATCHSIZE = ' + @BATCHSIZE + ','
IF @CHECK_CONSTRAINTS IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'CHECK_CONSTRAINTS,'
IF @CODEPAGE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'CODEPAGE = ''' + @CODEPAGE + ''','
IF @DATAFILETYPE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'DATAFILETYPE = ''' + @DATAFILETYPE + ''','
IF @DATA_SOURCE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'DATA_SOURCE = ''' + @DATA_SOURCE + ''','
IF @ERRORFILE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'ERRORFILE = ''' + @ERRORFILE + ''','
IF @ERRORFILE_DATA_SOURCE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'ERRORFILE_DATA_SOURCE = ''' + @ERRORFILE_DATA_SOURCE + ''','
IF @FIRSTROW IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FIRSTROW = ' + @FIRSTROW + ','
IF @FIRE_TRIGGERS IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FIRE_TRIGGERS,'
IF @FORMATFILE_DATASOURCE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FORMATFILE_DATASOURCE = ''' + @FORMATFILE_DATASOURCE + ''','
IF @KEEPIDENTITY IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'KEEPIDENTITY,'
IF @KEEPNULLS IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'KEEPNULLS,'
IF @KILOBYTES_PER_BATCH IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'KILOBYTES_PER_BATCH = ' + @KILOBYTES_PER_BATCH + ','
IF @LASTROW IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'LASTROW = ' + @LASTROW + ','
IF @MAXERRORS IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'MAXERRORS = ' + @MAXERRORS + ','
IF @ORDER IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'ORDER ( ' + @ORDER + ' ),'
IF @ROWS_PER_BATCH IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'ROWS_PER_BATCH = ' + @ROWS_PER_BATCH + ','
IF @TABLOCK IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'TABLOCK,'
-- bulk insert - input file format options
IF @FORMAT IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FORMAT = ''' + @FORMAT + ''','
IF @FIELDQUOTE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FIELDQUOTE = ''' + @FIELDQUOTE + ''','
IF @FORMATFILE IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FORMATFILE = ''' + @FORMATFILE + ''','
IF @FIELDTERMINATOR IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'FIELDTERMINATOR = ''' + @FIELDTERMINATOR + ''','
IF @ROWTERMINATOR IS NOT NULL SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + 'ROWTERMINATOR = ''' + @ROWTERMINATOR + ''','
-- Correct SQL query final character
IF RIGHT(@strSQL_Query,1) = ',' SET @strSQL_Query = LEFT(@strSQL_Query,LEN(@strSQL_Query)-1)
-- SQL close syntax
SET @strSQL_Query = @strSQL_Query + CHAR(13) + CHAR(10) + ')'
END
--TRUNCATE FIRST if specified
IF @TRUNCATE_FIRST = 1
BEGIN
DECLARE @strTRUNCSQL NVARCHAR(MAX) = 'TRUNCATE TABLE ' + @DESTINATION_TABLE
IF @DEBUG = 1 PRINT 'Truncating table specified: ' + @strTRUNCSQL
exec sp_executesql @strTRUNCSQL
END
IF @DEBUG = 1 PRINT 'Bulk Insert operation: ' + @strSQL_Query
EXEC sp_executesql @strSQL_Query
IF @CLEANUP_TEMP = 1
BEGIN
SET @strCMDSHELL = 'DEL /F /Q "' + @importFile + '"'
IF @DEBUG = 1 PRINT 'Clean-up after Bulk Import: EXEC xp_cmdshell ''' + @strCMDSHELL + ''''
EXEC xp_cmdshell @strCMDSHELL, no_output
END
END
将BULK INSERT放入在同一服务器上运行并执行该命令的Sql Agent作业中。