我目前有一个名为InvoiceFileName的变量名,它通过foreach循环创建.csv文件。然后将.csv列表输出到文件夹
然后,我将需要查询每个.csv文件,以选择每个.csv的标头和第一行数据。
我相信我需要使用OPENROWSET
来查询.csv。我有两个问题。
OPENROWSET
而无需插入表格。 下面是一个简单的OPENROWSET
,它只提供文件的标题。
SELECT
top 1 *
FROM OPENROWSET(BULK N'\\myservername\f$\reports\Invoices\CokeFiles\54ASBSd.csv', SINGLE_CLOB) AS Report
答案 0 :(得分:1)
您对数据库有什么样的权限?如果您拥有或者可以获得略微提升的权限,您可以使用BULK INSERT
和xp_cmdShell
来完成此任务,但是像@scsimon所说,您将不得不使用动态SQL。这是一个简单的例子:
-----------------------------------------------------------------------------------------------------
-- Set up your variables
-----------------------------------------------------------------------------------------------------
DECLARE
@folderPath AS VARCHAR(100) = '\\some\folder\path\here\',
@cmd AS VARCHAR(150), -- Will populate this with a command to get a list of files in a directory
@InvoiceFileName AS VARCHAR(100), -- Will be used in cursor loop
@targetTable AS VARCHAR(50) = 'SomeTable',
@fieldTerminator AS CHAR(1) = ',',
@rowTerminator AS CHAR(2) = '\n'
-----------------------------------------------------------------------------------------------------
-- Create a temp table to store the file names
-----------------------------------------------------------------------------------------------------
IF OBJECT_ID('tempdb..#FILE_LIST') IS NOT NULL
DROP TABLE #FILE_LIST
--
CREATE TABLE #FILE_LIST(FILE_NAME VARCHAR(255))
-----------------------------------------------------------------------------------------------------
-- Get a list of the files and store them in the temp table:
-- NOTE: this DOES require elevated permissions
-----------------------------------------------------------------------------------------------------
SET @cmd = 'dir "' + @folderPath + '" /b'
--
INSERT INTO #FILE_LIST(FILE_NAME)
EXEC Master..xp_cmdShell @cmd
--------------------------------------------------------------------------------
-- Here we remove any null values
--------------------------------------------------------------------------------
DELETE #FILE_LIST WHERE FILE_NAME IS NULL
-----------------------------------------------------------------------------------------------------
-- Set up our cursor and loop through the files
-----------------------------------------------------------------------------------------------------
DECLARE c1 CURSOR FOR SELECT FILE_NAME FROM #FILE_LIST
OPEN c1
FETCH NEXT FROM c1 INTO @InvoiceFileName
WHILE @@FETCH_STATUS <> -1
BEGIN -- Begin WHILE loop
BEGIN TRY
-- Bulk insert won't take a variable name, so dynamically generate the
-- SQL statement and execute it instead:
SET @sql = 'BULK INSERT ' + @targetTable + ' FROM ''' + @InvoiceFileName + ''' '
+ ' WITH (
FIELDTERMINATOR = ''' + @fieldTerminator + ''',
ROWTERMINATOR = ''' + @rowTerminator + ''',
FIRSTROW = 1,
LASTROW = 2
) '
EXEC (@sql)
END TRY
BEGIN CATCH
-- Handle errors here
END CATCH
-- Continue your loop
FETCH NEXT FROM c1 INTO @path,@filename
END -- End WHILE loop
-- Do what you need to do here with the data in your target table
一些免责声明:
BULK INSERT
和xp_cmdShell
的私有权限。
xp_cmdShell
(并且有充分的理由),但这是一个快速而肮脏的解决方案,对您的环境是什么做出了很多假设。
要通过SSIS执行此操作,理想情况下您可能需要use a format file for the bulk operation,但您必须始终格式化文件并删除SINGLE_CLOB选项。一个真正的hacky和非理想的方法是做这样的事情:
假设您的文件包含以下数据:
Col1,Col2,Col3,Col4
Here's,The,First,Line
Here's,The,Second,Line
Here's,The,Third,Line
Here's,The,Fourth,Line
然后你基本上可以解析这样的数据:
SELECT SUBSTRING(OnlyColumn, 0, CHARINDEX(CHAR(10), OnlyColumn, CHARINDEX(CHAR(10), OnlyColumn, 0)+1) )
FROM OPENROWSET(BULK '\\location\of\myFile.csv', SINGLE_CLOB) AS Report (OnlyColumn)
你的结果就是这样:
Col1,Col2,Col3,Col4 Here's,The,First,Line
这显然取决于您的行结尾是否一致,但如果您希望结果在单个列和单行中(就像使用SINGLE_CLOB选项的批量操作的行为一样),那么这应该可以满足您的需要。
您可以查看this SO post上的解决方案,了解有关如何将SSIS变量值作为参数传递给查询的信息。
答案 1 :(得分:0)