簡體   English   中英

SSIS OPENROWSET 查詢平面文件

[英]SSIS OPENROWSET query flat file

我目前有一個名為 InvoiceFileName 的變量名,它通過 foreach 循環創建 .csv 文件。 然后將 .csv 列表輸出到文件夾中。
然后我需要查詢每個 .csv 文件以選擇每個 .csv 的標題和第一行數據。 我相信我需要使用OPENROWSET來查詢 .csv。 我有2個問題。

  1. 查詢變量名 InvoiceFileName 的語法是什么。
  2. 是否可以在不插入表格的情況下選擇標題字段和第一行數據OPENROWSET

下面是一個簡單的OPENROWSET ,它只提供文件的標題。

SELECT 
top 1 *
FROM OPENROWSET(BULK N'\\myservername\f$\reports\Invoices\CokeFiles\54ASBSd.csv', SINGLE_CLOB) AS Report 

你對數據庫有什么樣的權限? 如果您擁有或可以獲得稍微提升的權限,您可以使用BULK INSERTxp_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

一些免責聲明:

  1. 我沒有測試過這段代碼。 只從我過去使用過的稍微復雜一點的 proc 復制過來,它正好適用於這種情況。
  2. 您需要提升BULK INSERTxp_cmdShell
  3. 我知道人們不xp_cmdShell使用xp_cmdShell (並且有充分的理由),但這是一個快速而骯臟的解決方案,對您的環境做出了很多假設。
  4. 這是假設您沒有在獲取變量中的每個文件時獲取數據。 如果是,您可以跳過此代碼的第一部分。
  5. 這段代碼還假設您在除了看到的一個 try/catch 塊之外的地方進行自己的錯誤處理。 為簡單起見,我省略了很多。

為了通過 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 變量值作為參數傳遞給查詢的信息。

使用 Foreach 循環容器查詢文件夾中的所有文件。 您可以使用通配符作為文件名,或使用 DTS 中的變量來設置組件的屬性。

在循環容器內,您可以將數據流任務與源文件連接、轉換和目標一起放置。

您可以通過將所有這些對象的屬性設置為 DTS 中的變量來修改所有這些對象的文件名和路徑。

通過循環內的表達任務,您可以更改 CSV 文件連接的路徑。

Foreach 循環編輯器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM