[英]SSIS OPENROWSET query flat file
我目前有一個名為 InvoiceFileName 的變量名,它通過 foreach 循環創建 .csv 文件。 然后將 .csv 列表輸出到文件夾中。
然后我需要查詢每個 .csv 文件以選擇每個 .csv 的標題和第一行數據。 我相信我需要使用OPENROWSET
來查詢 .csv。 我有2個問題。
OPENROWSET
。 下面是一個簡單的OPENROWSET
,它只提供文件的標題。
SELECT
top 1 *
FROM OPENROWSET(BULK N'\\myservername\f$\reports\Invoices\CokeFiles\54ASBSd.csv', SINGLE_CLOB) AS Report
你對數據庫有什么樣的權限? 如果您擁有或可以獲得稍微提升的權限,您可以使用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
使用xp_cmdShell
(並且有充分的理由),但這是一個快速而骯臟的解決方案,對您的環境做出了很多假設。為了通過 SSIS 執行此操作,理想情況下您可能需要使用格式文件進行批量操作,但您必須具有一致的格式文件並刪除 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 選項的批量操作的行為一樣),那應該可以滿足您的需求。
您可以查看此 SO 帖子上的解決方案,了解有關如何將 SSIS 變量值作為參數傳遞給查詢的信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.