2017-04-11 33 views
1

我正在嘗試編寫一個存儲過程來執行文件夾中的所有.sql文件,然後將結果輸出到CSV文件。如何創建一個動態查詢的臨時表,以便我可以BCP輸出

我的代碼:

DECLARE @Table table(
    [FileName] varchar(100), 
    depth int, 
    isFile int 
) 

DECLARE @Result int 
DECLARE @FileName VARCHAR(100) 
DECLARE @exportFile VARCHAR(100) 
DECLARE @ExportPath VARCHAR(100) 
DECLARE @SQLText VARCHAR(MAX) 
DECLARE @FilePath VARCHAR(100) 
DECLARE @FULLPATH VARCHAR(200) 
DECLARE @BULKEXEC NVARCHAR(MAX) 
DECLARE @Cmd nvarchar(1000) 

SET @FilePath = 'c:\temp' 
SET @ExportPath = 'c:\temp\output' 

INSERT INTO @Table 
EXEC master..xp_dirtree @FilePath,1,1 

DELETE FROM @Table WHERE isFile=0 

DECLARE FileList CURSOR STATIC FOR SELECT [FileName] FROM @Table WHERE FileName LIKE '%.sql' 
OPEN FileList 
FETCH FIRST FROM FileList INTO @FileName 
    WHILE @@Fetch_Status = 0 
     BEGIN 
      SET @exportFile = REPLACE(@FileName,'.sql','.csv') 
      SET @FULLPATH = @FilePath + '\' + @FileName 
      SET @BULKEXEC = 'SELECT @SQLText = BulkColumn FROM OPENROWSET(BULK ''' + @FULLPATH + ''', SINGLE_BLOB) as x' 

      EXEC sp_ExecuteSQL @BULKEXEC, N'@SQLText VARCHAR(MAX) output ', @SQLText output 

      EXEC (@SQLText) 



      SET @Cmd = 'bcp "SELECT * FROM ##Temptable" queryout "' + @ExportPath + '\' + @exportFile + '" -c -t, -T' 

      EXEC @Result = master..xp_cmdshell @cmd 

      FETCH NEXT FROM FileList INTO @FileName 
     END 
CLOSE FileList 
DEALLOCATE FileList 

這目前執行的文件,但我缺少上傳結果到##Temptable中間位。

有人能幫忙嗎?

+0

你能澄清你的_「我錯過了中間位」 _是什麼意思? –

+0

@TT。到目前爲止,我有運行查詢的代碼,以及一些將數據導出到csv的代碼。我無法編制代碼來填充## Temptable,以及執行SQLText的不同結果,以使我能夠導出查詢結果。或者,如果有更合適的方法將結果導出到csv文件,這可能是什麼。 – Leigh

回答

1

看看下面的例子。它使用@sqltext中的查詢,該查詢從INFORMATION_SCHEMA模式(tablescolumns)中選擇信息。

該查詢,然後修改,以將結果插入一個全局臨時表##tt,通過查找第一FROM關鍵字,並在適當的位置插入INTO ##tt。執行修改的查詢以將查詢的結果插入臨時表中。

最後,使用xp_cmdshell過程和BCP命令將結果寫入文本文件。


DECLARE @i INT=1; 
WHILE @i<10 
BEGIN 
    DECLARE @sqltext NVARCHAR(MAX); 
    IF @i%2=1 
     SET @sqltext='SELECT*FROM INFORMATION_SCHEMA.tables'; 
    ELSE 
     SET @sqltext='SELECT*FROM INFORMATION_SCHEMA.columns'; 

    DECLARE @ii INT; SET @ii=CHARINDEX('FROM',@sqltext); 

    SET @sqltext=LEFT(@sqltext,@ii-1)+' INTO ##tt '+SUBSTRING(@sqltext,@ii,LEN(@sqltext)); 
    EXEC(@sqltext); 

    DECLARE @bcp_cmd NVARCHAR(4000); 
    SET @bcp_cmd='BCP "SELECT*FROM ##tt" QUERYOUT "c:\temp\tt'+CAST(@i AS NVARCHAR)+'.txt" -c -t, -T -d ' + DB_NAME() + ' -S '+ @@SERVERNAME; 
    EXEC xp_cmdshell @bcp_cmd; 

    DROP TABLE ##tt; 
    SET @[email protected]+1; 
END 

如果是不可能的,因爲它們是複雜的腳本來格式化在.sql文件的查詢,該sqlcmd實用性方面會有一個更容易使用。您可以使用-i指定輸入文件(您的SQL腳本),並使用-o指定一個輸出文件(CSV文件)。用於柱分離器的-s等。

+0

感謝您的快速響應。我已經考慮在查詢中插入INTO命令,這將是一個很好的解決方案,因爲## Temptable將由查詢本身創建。不幸的是,這個解決方案不適用於這種情況,因爲一些查詢非常複雜,有時候還有臨時表和/或子查詢,因此在主FROM之前有一個FROM。 – Leigh

+0

@Leigh在答案中添加了BCP的替代方案。 –

+0

sqlcmd指針只是我正在尋找的幫助。謝謝! – Leigh

1

如果別人正在做類似我工作的代碼如下:

DECLARE @Table table(
     [FileName] varchar(100), 
     depth int, 
     isFile int 
    ) 

    DECLARE @Result int 
    DECLARE @FilePath VARCHAR(100) 
    DECLARE @FileName VARCHAR(100) 
    DECLARE @Fullpath VARCHAR(200) 
    DECLARE @exportFile VARCHAR(100) 
    DECLARE @ExportPath VARCHAR(100) 
    DECLARE @FullExportPath AS VARCHAR(200) 
    DECLARE @Cmd nvarchar(1000) 


    SET @FilePath = '\\192.168.7.111\c$\temp' 
    SET @ExportPath = '\\192.168.7.111\c$\temp\output' 

    INSERT INTO @Table 
    EXEC master..xp_dirtree @FilePath,1,1 

    DELETE FROM @Table WHERE isFile=0 

    DECLARE FileList CURSOR STATIC FOR SELECT [FileName] FROM @Table WHERE FileName LIKE '%.sql' 
    OPEN FileList 
    FETCH FIRST FROM FileList INTO @FileName 
     WHILE @@Fetch_Status = 0 
      BEGIN 
       SET @exportFile = REPLACE(@FileName,'.sql','.csv') 
       SET @FullExportPath = @ExportPath + '\' + @exportFile 
       SET @Fullpath = @FilePath + '\' + @FileName 
       SET @cmd = 'sqlcmd -i "' + @Fullpath + '" -o "' + @FullExportPath + '" -h-1 -s"," -W' 

       EXEC @Result = master..xp_cmdshell @cmd 

       FETCH NEXT FROM FileList INTO @FileName 
      END 
    CLOSE FileList 
    DEALLOCATE FileList 
相關問題