2012-06-14 33 views
2

存儲過程我有一個有趣的劇本:將數據導出爲CSV文件只出口到一個文件

DECLARE @StartDT DATE 
DECLARE @MinDOS DATE 
DECLARE @TableName VARCHAR(50) 
SET @TableName = 'ViewAccountDetail' 
SELECT @MinDOS = MIN(dos) FROM accn_demographics 
SELECT @StartDT = 
    CAST(CAST(datepart(YYYY,@MinDOS) AS varchar) + '-' + CAST(datepart(mm,@MinDOS) AS varchar) + '-' + CAST('01' AS varchar) AS DATETIME) 
DECLARE @FileLocation VARCHAR(50) 

WHILE @StartDT < '20110901' 
BEGIN 
    SET @FileLocation='C:\test\'[email protected]+cast(@StartDT as varchar)+'.csv' 
    EXEC BCP_Text_File @TableName, @FileLocation  
    SET @StartDT = DATEADD(MONTH,1,@StartDT) 
END 

這是應該做的是出口數據爲CSV文件。該文件的名稱應該是:

C:\test\ViewAccountDetail2011-01-01.csv 
C:\test\ViewAccountDetail2011-02-01.csv 
C:\test\ViewAccountDetail2011-03-01.csv 
C:\test\ViewAccountDetail2011-04-01.csv 
C:\test\ViewAccountDetail2011-05-01.csv 
C:\test\ViewAccountDetail2011-06-01.csv 
C:\test\ViewAccountDetail2011-07-01.csv 
C:\test\ViewAccountDetail2011-08-01.csv 

,但所有的數據存儲到同一個:

C:\test\ViewAccountDetail2011-01-01.csv 

我做了print @FileLocation,並確認它可以正確地更新這個變量。

有沒有任何明顯的,顯而易見的東西,我在這裏失蹤?

FYI這一行:

EXEC BCP_Text_File @TableName, @FileLocation 

調用這個程序:

ALTER PROCEDURE [dbo].[BCP_Text_File] 
    @table NVARCHAR(255), 
    @filename VARCHAR(100) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    IF OBJECT_ID(@table) IS NOT NULL 
    BEGIN 
    DECLARE 
     @sql NVARCHAR(MAX), 
     @cols NVARCHAR(MAX) = N''; 

    SELECT @cols += ',' + name 
     FROM sys.columns 
     WHERE [object_id] = OBJECT_ID(@table) 
     ORDER BY column_id; 

    SELECT @cols = STUFF(@cols, 1, 1, ''); 

    SET @sql = N'EXEC master..xp_cmdshell ''bcp "SELECT ''''' 
     + REPLACE(@cols, ',', ''''',''''') + ''''' UNION ALL SELECT ' 
     + 'RTRIM(' + REPLACE(@cols, ',', '),RTRIM(') + ') FROM ' 
     + DB_NAME() + '..' + @table + '" queryout "' + @filename + '" -c -T'''; 

    EXEC sp_executesql @sql; 
    END 
    ELSE 
    BEGIN 
    SELECT 'The table '[email protected]+' does not exist in the database'; 
    END 
END 

GO 

非常感謝你的幫助和指導!

+0

重新寫入該行作爲'SET @ FileLocation = 'C:\測試\'。+ @表名+轉換(VARCHAR(20),@ StartDT)+」 csv'' – Rab

+1

嘗試減少代碼以只需幾行即可解決問題的核心問題,而不需要對外部程序進行任何調用。然後我們可以嘗試爲自己運行代碼。如果我要調試這個,我想要一些東西,我可以複製粘貼到SSMS並運行,不會出現任何錯誤,缺少表格,缺少存儲過程等。換句話說,使它成爲一個簡單的,自包含的示例,錯誤。 –

+0

嘗試更改這一個'SET @StartDT = DATEADD(month,1,@ StartDT)' – Rab

回答

7

似乎適合我。我有幾點建議:

(1)停止做所有的字符串連接來建立一個日期。你可以做同樣的事情更容易,如:

SELECT @StartDT = DATEADD(MONTH, DATEDIFF(MONTH, '19000101', @MinDOS), '19000101'); 

(2)stop declaring varchar without length。並確保正確的輸出,我更喜歡轉換:

SET @FileLocation = 'C:\test\' + @TableName 
    + CONVERT(CHAR(10), @StartDT, 120) + '.csv'; 

(3),而不是「調試」通過運行存儲過程,並在文件夾中檢查輸出的代碼,爲什麼不理智,先檢查一下你的輸入?另外,爲什麼在日期中使用兩個變量?

DECLARE 
    @StartDT DATE, 
    @TableName NVARCHAR(50), 
    @FileLocation VARCHAR(255); 

SET @TableName = N'ViewAccountDetail'; 

SELECT @StartDT = DATEADD(MONTH, DATEDIFF(MONTH, '19000101', MIN(dos)), '19000101') 
    FROM dbo.accn_demographics; 

    PRINT @StartDT; 
-- ^^^^^ debugging 101 - what month do we think we're starting at? 

WHILE @StartDT < '20110901' 
BEGIN 
    SET @FileLocation = 'C:\test\' + @TableName 
     + CONVERT(CHAR(10), @StartDT, 120) + '.csv'; 

     PRINT @FileLocation; 
    --^^^^^ again, debugging 101 - what does the filename currently look like? 

    --EXEC BCP_Text_File @TableName, @FileLocation  
    SET @StartDT = DATEADD(MONTH, 1, @StartDT); 
END