如何将几个CSV文件批量加载到SQL Server?

时间:2018-10-01 01:02:04

标签: sql sql-server

我将下面的代码拼凑在一起。我可以将文件路径写入表中,但是不能使用表中的路径将CSV文件批量加载到文件夹中。这里的一些专家可以看看一下,让我知道怎么了吗? TIA。

IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL
DROP TABLE #DirectoryTree;

CREATE TABLE #DirectoryTree (
       id int IDENTITY(1,1)
      ,subdirectory nvarchar(512)
      ,depth int
      ,isfile bit);

INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree 'C:\my_path\CSV Files\',1,1;


SELECT * FROM #DirectoryTree
WHERE isfile = 1 AND RIGHT(subdirectory,4) = '.csv'
ORDER BY id;
GO
DROP TABLE ALLFILENAMES
--CREATE TABLE ALLFILENAMES(id VARCHAR(999),subdirectory VARCHAR(255),depth VARCHAR(1),isfile VARCHAR(1))

Select * INTO ALLFILENAMES
From #DirectoryTree


--code above is fine; problems start here
--cursor loop
--bulk insert won't take a variable name, so make a sql and execute it instead:
Declare @sql varchar(8000)
set @sql = 'BULK INSERT BULKACT FROM ''' + 'ALLFILENAMES.subdirectory' + ''' '
    + '     WITH ( 
            DATAFILETYPE = ''char'', 
            FIELDTERMINATOR = '','', 
            ROWTERMINATOR = ''\n'', 
            FIRSTROW = 2 
        ) '
print @sql
exec (@sql)

问题在于批量插入。这是我收到的错误消息:消息4860,级别16,状态1,第28行 无法批量加载。文件“ ALLFILENAMES.subdirectory”不存在。

因此,“ ALLFILENAMES”是表的名称,“ subdirectory”是包含所有CSV文件的所有路径的字段的名称。

2 个答案:

答案 0 :(得分:1)

您需要从该ALLFILENAMES表中进行选择。您不能像这样指定表名+列名并期望它能工作

还需要在FROM文件名中指定完整路径

,您可以将临时表用于ALLFILENAMES而不是永久的tble

Declare @sql varchar(max)
select   @sql = isnull(@sql , '')
    + 'BULK INSERT BULKACT FROM ''C:\my_path\CSV Files\' + ALLFILENAMES.subdirectory + ''' '
    + '     WITH ( 
            DATAFILETYPE = ''char'', 
            FIELDTERMINATOR = '','', 
            ROWTERMINATOR = ''\n'', 
            FIRSTROW = 2 
        ); ' + char(13)
from    ALLFILENAMES
print @sql

并且有一个WITH (FORMAT = 'CSV');选项可用于从CSV文件批量插入

答案 1 :(得分:1)

感谢您的帮助,Sqiurrel。我得到了下面的代码,可以工作,并添加一些注释。这确实很丑。我想SQL Server确实不是为这类事情而设计的...

----------------------------------------------------------
-- Create 5 tables and all fields in tables
DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5)
BEGIN

declare @cmd nvarchar(1000), 
@MyTableName nvarchar(100)
print str(@intFlag)

set @MyTableName = 'CSV' + replace(str(@intFlag),' ','')
print @MyTableName
set @cmd = 'CREATE TABLE dbo.' + quotename(@MyTableName, '[') + '(Name varchar(255), Address varchar(255), Age varchar(255), Work varchar(255));';
print @cmd
exec(@cmd)

SET @intFlag = @intFlag + 1

END
GO

----------------------------------------------------------

IF OBJECT_ID('tempdb..#DirectoryTree') IS NOT NULL
DROP TABLE #DirectoryTree;

CREATE TABLE #DirectoryTree (
       id int IDENTITY(1,1)
      ,subdirectory nvarchar(512)
      ,depth int
      ,isfile bit);

INSERT #DirectoryTree (subdirectory,depth,isfile)
EXEC master.sys.xp_dirtree 'C:\your_path_here\',1,1;

SELECT * FROM #DirectoryTree
WHERE isfile = 1 AND RIGHT(subdirectory,4) = '.csv'
ORDER BY id;
GO

DROP TABLE ALLFILENAMES
Select * INTO ALLFILENAMES
From #DirectoryTree

----------------------------------------------------------

--cursor loop
--bulk insert won't take a variable name, so make a sql and execute it instead:
Declare @sql varchar(max)
select   @sql = isnull(@sql , '')
    + 'BULK INSERT ' + ALLFILENAMES.subdirectory + ' FROM ''C:\your_path_here\' + ALLFILENAMES.subdirectory + ''' '
    + '     WITH ( 
            DATAFILETYPE = ''char'', 
            FIELDTERMINATOR = '','', 
            ROWTERMINATOR = ''\n'', 
            FIRSTROW = 2 
        ); ' + char(13)
from   ALLFILENAMES
print @sql
exec (@sql)

----------------------------------------