How to turn one column of a table into a csv string in SQL Server without using a cursor

前端 未结 5 1698
灰色年华
灰色年华 2020-12-14 18:02

I want to return the results of select Column from Table into a comma separated string using SQL Server.

The column in question is rather large (n

5条回答
  •  北荒
    北荒 (楼主)
    2020-12-14 18:24

    I've created a proc that will dynamically create a CSV out of any arbitrary table, without needing to explicitly specify the columns. This is useful if you don't want to write custom code every time you want to turn a SQL table into a CSV string.

    -- Description: Turns a query into a formatted CSV.
    -- Any ORDER BY clause needs to be passed in the separate ORDER BY parameter.
    CREATE PROC [dbo].[spQueryToCsv] 
    (
      @query nvarchar(MAX), --A query to turn into CSV format. It should not include an ORDER BY clause.
      @orderBy nvarchar(MAX) = NULL, --An optional ORDER BY clause. It should contain the words 'ORDER BY'.
      @csv nvarchar(MAX) = NULL OUTPUT --The CSV output of the procedure.
    )
    AS
    BEGIN   
      SET NOCOUNT ON;
    
      IF @orderBy IS NULL BEGIN
        SET @orderBy = '';
      END
    
      SET @orderBy = REPLACE(@orderBy, '''', '''''');  
    
      DECLARE @realQuery nvarchar(MAX) = '
        DECLARE @headerRow nvarchar(MAX);
        DECLARE @cols nvarchar(MAX);
    
        SELECT * INTO #dynSql FROM (' + @query + ') sub;    
    
        SELECT @cols = ISNULL(@cols + '' + '''','''' + '', '''') + ''''''"'''' + ISNULL(REPLACE(CAST(['' + name + ''] AS nvarchar(max)), ''''"'''', ''''""''''), '''''''') + ''''"''''''
        FROM tempdb.sys.columns 
        WHERE object_id = object_id(''tempdb..#dynSql'')
        ORDER BY column_id;        
    
        SET @cols = ''
          SET @csv = (SELECT '' + @cols + '' FROM #dynSql ' + @orderBy + ' FOR XML PATH(''''m_m''''));
          ''
        EXEC sys.sp_executesql @cols, N''@csv nvarchar(MAX) OUTPUT'', @csv=@csv OUTPUT    
    
        SELECT @headerRow = ISNULL(@headerRow + '','', '''') + ''"'' + REPLACE(name, ''"'', ''""'') + ''"''
        FROM tempdb.sys.columns 
        WHERE object_id = object_id(''tempdb..#dynSql'')
        ORDER BY column_id;
    
        SET @headerRow = @headerRow + CHAR(13) + CHAR(10);
    
        SET @csv = @headerRow + @csv;    
        ';
    
      EXEC sys.sp_executesql @realQuery, N'@csv nvarchar(MAX) OUTPUT', @csv=@csv OUTPUT
      SET @csv = REPLACE(REPLACE(@csv, '', ''), '', CHAR(13) + CHAR(10))
    END
    
    GO
    

    Usage:

    DECLARE @csv nvarchar(max)
    EXEC [dbo].[spQueryToCsv]  @query = 'SELECT * FROM Customers', @csv = @csv OUTPUT, @orderBy = 'ORDER BY CustomerId'
    SELECT @csv
    

    This is based on similar code I wrote to turn an arbitrary table into an HTML string.

提交回复
热议问题