如何为动态查询创建临时表,以便我可以BCP输出

时间:2017-04-11 11:32:51

标签: sql-server sql-server-2012 bcp

我正在尝试编写一个存储过程来执行文件夹中的所有.sql个文件,然后将结果输出到CSV文件。

我的代码:

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的中间位。

有人能帮忙吗?

2 个答案:

答案 0 :(得分: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 @i=@i+1;
END

如果无法格式化.sql文件中的查询,因为它们是复杂的脚本,sqlcmd实用程序将更容易使用。您可以使用-i指定输入文件(SQL脚本),使用-o指定输出文件(CSV文件)。 -s用于列分隔符,依此类推。

答案 1 :(得分: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