使用查询或存储过程将文本文件导入 SQL 服务器 table
Import text file into SQL server table using query or stored procedure
我想每天将文件夹中的文本文件导入 sql 服务器 table。我可以使用批量插入来做到这一点,但每日文本文件名不同,然后我必须更改脚本(仅文件名)。一旦我们在文件夹中收到文件并且 sp 可以动态读取文件名,有什么方法可以导出文件。
这种任务最好用SSIS来完成。但有时 SSIS 需要开发人员额外的依赖项。所以他们尝试使用 SQL 服务器来做到这一点。
因此您可以使用以下 SETPS 来完成此操作。它会从特定位置动态读取您的文本文件,并在读取后移动到另一个位置。
假设您有以下数据库和table。
CREATE DATABASE [Codefirst]
GO
USE [Codefirst]
GO
CREATE TABLE [dbo].[tbl_NewVendorData](
[AccountNumber] [nvarchar](15) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[ModificationDate] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[AccountNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
并且您在需要插入到 table 的文本文件中有以下文本数据。阅读后您还需要将文件移动到另一个位置。
只需将以下数据复制并粘贴到您的文本文件中即可。
AC001
,Raju Ahmed,
1989-11-18 00:00:00.000;
AC002
,Robin Hossain,
1991-12-08 00:00:00.000;
AC003
,Raju Ahmed 2,
1989-11-18 00:00:00.000;
AC004
,Raju Ahmed 3,
1989-11-10 00:00:00.000;
AC005
,Raju Ahmed 4,
1989-11-12 00:00:00.000;
AC006
,Raju Ahmed 5,
1989-11-19 00:00:00.000;
AC007
,Raju Ahmed 6,
1989-11-02 00:00:00.000;
AC008
,Raju Ahmed 7,
1989-11-10 00:00:00.000;
AC009
,Raju Ahmed 8,
1989-05-18 00:00:00.000;
AC010
,Raju Ahmed 9,
1989-10-13 00:00:00.000;
AC011
,Raju Ahmed 10,
1989-01-16 00:00:00.000;
AC012
,Raju Ahmed 11,
1989-01-14 00:00:00.000;
SETP:1创建以下SP。假设你的@oldDir='C:\Data' 和
@newDir='C:\Data2'。 @oldDir 表示将从这里读取您的文本文件 & @newDir 表示读取后文件将移动到哪里。
CREATE PROC uspReadTextFileAndMove
(
@oldDir VARCHAR(1000)='C:\Data',
@newDir VARCHAR(1000)='C:\Data2'
)
AS
BEGIN
DECLARE @command VARCHAR(1000);
DECLARE @insertCommand VARCHAR(1000);
DECLARE @cmdFileMove VARCHAR(1000);
DECLARE @files TABLE ([Id] INT IDENTITY, [FileName] VARCHAR(1000));
DECLARE @FileToRead VARCHAR(1000)
SET @command = 'dir /b ' + @oldDir;
INSERT INTO @files EXECUTE xp_cmdshell @command;
DECLARE fileReadCursor CURSOR FOR
SELECT [FileName] FROM @files
OPEN fileReadCursor;
FETCH fileReadCursor INTO @FileToRead;
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @insertCommand= 'BULK INSERT [dbo].[tbl_NewVendorData] FROM ''' +@oldDir+'\'+ @FileToRead + ''' WITH ( FIELDTERMINATOR='','', ROWTERMINATOR='';\n'');'
EXECUTE(@insertCommand);
SET @cmdFileMove= 'MOVE ' + @oldDir + '\' + @FileToRead +' '+ @newDir +'\'+@FileToRead
EXEC master..xp_cmdshell @cmdFileMove
--PRINT @insertCommand;
--PRINT @FileToRead;
--PRINT @cmdFileMove;
FETCH fileReadCursor INTO @FileToRead;
END;
CLOSE fileReadCursor;
DEALLOCATE fileReadCursor;
END
STEP:2 创建一个 SQL 服务器 Job Schedular 以每天或每小时或任何你想要的方式执行 STEP: 1。
根据您的需要按照以下脚本中的注释行和 运行 脚本进行更改以创建作业调度程序,该程序将 运行 每 1 分钟后一次(您可以更改它每小时、每天等)&它将执行我们的 SP。
USE tempdb
GO
IF OBJECT_ID('##tempJobTableConfig', 'U') IS NOT NULL
BEGIN
DROP TABLE ##tempJobTableConfig;
END
DECLARE @DatabaseName VARCHAR(200)='Codefirst' --Change Here: Change Your Database name.
DECLARE @TrialDays INT = 0 --Change Here: Change your trial days number from @TrialDays variable.
DECLARE @freq_subday_type_Variable INT= 4 --if you want it as minute change it value as 4,If value is 8 then it will be hour,
DECLARE @freq_subday_interval_Variable INT=1 --Change here as: If your @freq_subday_type=8 then 12 will be hour, @freq_subday_type=4 then 12 will be minutes,
SELECT @DatabaseName AS DatabaseName
,DATEADD(DAY,@TrialDays,GETDATE()) AS ExpairationDate
,ISNULL(@freq_subday_type_Variable,4) AS freq_subday_type_Variable
,ISNULL(@freq_subday_interval_Variable,15) AS freq_subday_interval_Variable
INTO ##tempJobTableConfig
USE [msdb]
GO
DECLARE @jobId2 BINARY(16)
SELECT @jobId2 = job_id FROM msdb.dbo.sysjobs WHERE (name = N'TextFileReadAndMoveJob')
IF (@jobId2 IS NOT NULL)
BEGIN
EXEC msdb.dbo.sp_delete_job @jobId2
END
BEGIN TRANSACTION
DECLARE @DateInIntData INT
DECLARE @jobId BINARY(16)
DECLARE @ReturnCode INT
DECLARE @User NVARCHAR(500)=(SELECT SUSER_NAME())
/*===========================================================================================================================================================================
Value of @DateInIntData will be like this =20210224, where 2021=year,02=month & 24=day & it'll dynamically add current date as your schedular start date.
=============================================================================================================================================================================*/
SELECT @ReturnCode = 0
SET @DateInIntData=CAST(
(CAST((SELECT DATEPART(YEAR,GETDATE())) AS VARCHAR(4))
+RIGHT('00'+CAST((SELECT DATEPART(MONTH,GETDATE())) AS VARCHAR(4)),2)
+RIGHT('00'+CAST((SELECT DATEPART(DAY,GETDATE())) AS VARCHAR(4)),2))
AS INT)
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'TextFileReadAndMoveJob',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'No description available.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=@User, @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
DECLARE @databaseValue VARCHAR(400)=(SELECT DatabaseName FROM tempdb..##tempJobTableConfig)
DECLARE @commandValue NVARCHAR(500)=N'USE '+@databaseValue+'
GO
EXEC uspReadTextFileAndMove;
'
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Execution',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=@commandValue,
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
DECLARE @schedule_uid2 NVARCHAR(500)=(SELECT NEWID())
DECLARE @freq_subday_type_Value INT=(SELECT ISNULL(freq_subday_type_Variable,4) FROM tempdb..##tempJobTableConfig)
DECLARE @freq_subday_interval_Value INT=(SELECT ISNULL(freq_subday_interval_Variable,4) FROM tempdb..##tempJobTableConfig)
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'TextFileReadAndMoveJobSchedule',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=@freq_subday_type_Value,
@freq_subday_interval=@freq_subday_interval_Value,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=@DateInIntData,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959,
@schedule_uid=@schedule_uid2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO
注意:您可能需要启用'xp_cmdshell的权限。为此,请执行以下代码。
-- this turns on advanced options and is needed to configure xp_cmdshell
EXEC sp_configure 'show advanced options', '1'
RECONFIGURE
-- this disables xp_cmdshell
EXEC sp_configure 'xp_cmdshell', '0'
RECONFIGURE
我想每天将文件夹中的文本文件导入 sql 服务器 table。我可以使用批量插入来做到这一点,但每日文本文件名不同,然后我必须更改脚本(仅文件名)。一旦我们在文件夹中收到文件并且 sp 可以动态读取文件名,有什么方法可以导出文件。
这种任务最好用SSIS来完成。但有时 SSIS 需要开发人员额外的依赖项。所以他们尝试使用 SQL 服务器来做到这一点。
因此您可以使用以下 SETPS 来完成此操作。它会从特定位置动态读取您的文本文件,并在读取后移动到另一个位置。
假设您有以下数据库和table。
CREATE DATABASE [Codefirst]
GO
USE [Codefirst]
GO
CREATE TABLE [dbo].[tbl_NewVendorData](
[AccountNumber] [nvarchar](15) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[ModificationDate] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED
(
[AccountNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
并且您在需要插入到 table 的文本文件中有以下文本数据。阅读后您还需要将文件移动到另一个位置。 只需将以下数据复制并粘贴到您的文本文件中即可。
AC001 | ,Raju Ahmed, | 1989-11-18 00:00:00.000; |
---|---|---|
AC002 | ,Robin Hossain, | 1991-12-08 00:00:00.000; |
AC003 | ,Raju Ahmed 2, | 1989-11-18 00:00:00.000; |
AC004 | ,Raju Ahmed 3, | 1989-11-10 00:00:00.000; |
AC005 | ,Raju Ahmed 4, | 1989-11-12 00:00:00.000; |
AC006 | ,Raju Ahmed 5, | 1989-11-19 00:00:00.000; |
AC007 | ,Raju Ahmed 6, | 1989-11-02 00:00:00.000; |
AC008 | ,Raju Ahmed 7, | 1989-11-10 00:00:00.000; |
AC009 | ,Raju Ahmed 8, | 1989-05-18 00:00:00.000; |
AC010 | ,Raju Ahmed 9, | 1989-10-13 00:00:00.000; |
AC011 | ,Raju Ahmed 10, | 1989-01-16 00:00:00.000; |
AC012 | ,Raju Ahmed 11, | 1989-01-14 00:00:00.000; |
SETP:1创建以下SP。假设你的@oldDir='C:\Data' 和 @newDir='C:\Data2'。 @oldDir 表示将从这里读取您的文本文件 & @newDir 表示读取后文件将移动到哪里。
CREATE PROC uspReadTextFileAndMove
(
@oldDir VARCHAR(1000)='C:\Data',
@newDir VARCHAR(1000)='C:\Data2'
)
AS
BEGIN
DECLARE @command VARCHAR(1000);
DECLARE @insertCommand VARCHAR(1000);
DECLARE @cmdFileMove VARCHAR(1000);
DECLARE @files TABLE ([Id] INT IDENTITY, [FileName] VARCHAR(1000));
DECLARE @FileToRead VARCHAR(1000)
SET @command = 'dir /b ' + @oldDir;
INSERT INTO @files EXECUTE xp_cmdshell @command;
DECLARE fileReadCursor CURSOR FOR
SELECT [FileName] FROM @files
OPEN fileReadCursor;
FETCH fileReadCursor INTO @FileToRead;
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @insertCommand= 'BULK INSERT [dbo].[tbl_NewVendorData] FROM ''' +@oldDir+'\'+ @FileToRead + ''' WITH ( FIELDTERMINATOR='','', ROWTERMINATOR='';\n'');'
EXECUTE(@insertCommand);
SET @cmdFileMove= 'MOVE ' + @oldDir + '\' + @FileToRead +' '+ @newDir +'\'+@FileToRead
EXEC master..xp_cmdshell @cmdFileMove
--PRINT @insertCommand;
--PRINT @FileToRead;
--PRINT @cmdFileMove;
FETCH fileReadCursor INTO @FileToRead;
END;
CLOSE fileReadCursor;
DEALLOCATE fileReadCursor;
END
STEP:2 创建一个 SQL 服务器 Job Schedular 以每天或每小时或任何你想要的方式执行 STEP: 1。
根据您的需要按照以下脚本中的注释行和 运行 脚本进行更改以创建作业调度程序,该程序将 运行 每 1 分钟后一次(您可以更改它每小时、每天等)&它将执行我们的 SP。
USE tempdb
GO
IF OBJECT_ID('##tempJobTableConfig', 'U') IS NOT NULL
BEGIN
DROP TABLE ##tempJobTableConfig;
END
DECLARE @DatabaseName VARCHAR(200)='Codefirst' --Change Here: Change Your Database name.
DECLARE @TrialDays INT = 0 --Change Here: Change your trial days number from @TrialDays variable.
DECLARE @freq_subday_type_Variable INT= 4 --if you want it as minute change it value as 4,If value is 8 then it will be hour,
DECLARE @freq_subday_interval_Variable INT=1 --Change here as: If your @freq_subday_type=8 then 12 will be hour, @freq_subday_type=4 then 12 will be minutes,
SELECT @DatabaseName AS DatabaseName
,DATEADD(DAY,@TrialDays,GETDATE()) AS ExpairationDate
,ISNULL(@freq_subday_type_Variable,4) AS freq_subday_type_Variable
,ISNULL(@freq_subday_interval_Variable,15) AS freq_subday_interval_Variable
INTO ##tempJobTableConfig
USE [msdb]
GO
DECLARE @jobId2 BINARY(16)
SELECT @jobId2 = job_id FROM msdb.dbo.sysjobs WHERE (name = N'TextFileReadAndMoveJob')
IF (@jobId2 IS NOT NULL)
BEGIN
EXEC msdb.dbo.sp_delete_job @jobId2
END
BEGIN TRANSACTION
DECLARE @DateInIntData INT
DECLARE @jobId BINARY(16)
DECLARE @ReturnCode INT
DECLARE @User NVARCHAR(500)=(SELECT SUSER_NAME())
/*===========================================================================================================================================================================
Value of @DateInIntData will be like this =20210224, where 2021=year,02=month & 24=day & it'll dynamically add current date as your schedular start date.
=============================================================================================================================================================================*/
SELECT @ReturnCode = 0
SET @DateInIntData=CAST(
(CAST((SELECT DATEPART(YEAR,GETDATE())) AS VARCHAR(4))
+RIGHT('00'+CAST((SELECT DATEPART(MONTH,GETDATE())) AS VARCHAR(4)),2)
+RIGHT('00'+CAST((SELECT DATEPART(DAY,GETDATE())) AS VARCHAR(4)),2))
AS INT)
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'TextFileReadAndMoveJob',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'No description available.',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=@User, @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
DECLARE @databaseValue VARCHAR(400)=(SELECT DatabaseName FROM tempdb..##tempJobTableConfig)
DECLARE @commandValue NVARCHAR(500)=N'USE '+@databaseValue+'
GO
EXEC uspReadTextFileAndMove;
'
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Execution',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=@commandValue,
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
DECLARE @schedule_uid2 NVARCHAR(500)=(SELECT NEWID())
DECLARE @freq_subday_type_Value INT=(SELECT ISNULL(freq_subday_type_Variable,4) FROM tempdb..##tempJobTableConfig)
DECLARE @freq_subday_interval_Value INT=(SELECT ISNULL(freq_subday_interval_Variable,4) FROM tempdb..##tempJobTableConfig)
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'TextFileReadAndMoveJobSchedule',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=@freq_subday_type_Value,
@freq_subday_interval=@freq_subday_interval_Value,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=@DateInIntData,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959,
@schedule_uid=@schedule_uid2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO
注意:您可能需要启用'xp_cmdshell的权限。为此,请执行以下代码。
-- this turns on advanced options and is needed to configure xp_cmdshell
EXEC sp_configure 'show advanced options', '1'
RECONFIGURE
-- this disables xp_cmdshell
EXEC sp_configure 'xp_cmdshell', '0'
RECONFIGURE