2

我很好奇这是否可能。

我有一个表,或者这可能特定于任何带有数据的旧表。一个简单的 SELECT 将返回列和行作为结果集。我试图找出是否可以返回行而不是列,列连接并以逗号分隔。因此,预期的行数返回,但只有一个 varchar 列包含所有列的逗号分隔结果,就像 CSV 文件一样。

谢谢。

[更新]

这是我要问的更多细节。我没有在客户端上执行此操作的选项,这是我尝试使用 SSIS 完成的任务。

场景:我有一个在 SSIS 中动态创建的表,但每次构建时列名都会更改。原始包使用 BCP 来获取数据并将其放入平面文件中,但由于在作为作业运行时的权限,BCP 无法在所需的目的地创建平面文件。我们也不能改变这个。

另一个问题是,使用 SSIS 2005,使用平面文件目标,您必须从输入源映射列名,我不能这样做,因为列名不断变化。

我编写了一个脚本任务来从原始表中获取所有数据,然后使用流写入器写入 CSV,但我必须遍历每一行,然后遍历每一列,以生成由所有列组成的字符串。我想针对带有 vb.net 的讨厌循环来测量 sql server 上的这种列连接的性能。

如果我可以让 sql 为每一行生成一个列,我可以将一行写入文本文件,而不是遍历每一列来构建行。

4

5 回答 5

1

我认为你应该试试这个

    SELECT UserName +','+ Password AS ColumnZ
FROM UserTable
于 2013-01-09T08:56:24.557 回答
0

这可能需要清理一些,但您可以通过使用存储在动态 SQL 中sys.objectssys.columns与动态 SQL 一起使用的元数据来做到这一点。请注意,我不是动态 SQL 的粉丝,但出于报告目的,它应该不是太大的问题。

一些用于创建测试数据的 SQL:

if (object_id('test') is not null)
drop table test;

create table test
(
id uniqueidentifier not null default newId()
,col0 nvarchar(255)
,col1 nvarchar(255)
,col2 nvarchar(255)
,col3 nvarchar(255)
,col4 nvarchar(255)
);

insert into test (col0,col1,col2,col3,col4)
select 'alice','bob','charlie','dave','emily'
union
select 'abby','bill','charlotte','daniel','evan'

用于构建 CSV 行的存储过程:

-- emit the contents of a table as a CSV.
-- @table_name: name of a permanent (in sys.objects) table 
-- @debug: set to 1 to print the generated query
create procedure emit_csv(@table_name nvarchar(max), @debug bit = 0)
as

    declare @object_id int;

    set nocount on;

    set @object_id = object_id(@table_name);

    declare @name nvarchar(max);
    declare db_cursor cursor for
        select name 
        from sys.columns 
        where object_id = @object_id;

    open db_cursor;
    fetch next from db_cursor into @name

    declare @query nvarchar(max);
    set @query = '';

    while @@FETCH_STATUS = 0
    begin
        -- TODO: modify appended clause to escape commas in addition to trimming
        set @query = @query + 'rtrim(cast('+@name+' as nvarchar(max)))'
        fetch next from db_cursor into @name;

        -- add concatenation to the end of the query. 
        -- TODO: Rearrange @query construction order to make this unnecessary
        if (@@fetch_status = 0)
            set @query = @query + ' + '','' +'
    end;


    close db_cursor;
    deallocate db_cursor;

    set @query = 'select rtrim('+@query+')  as csvrow from '+@table_name;
    if @debug != 0
    begin
        declare @newline nvarchar(2);
        set @newline = char(13) + char(10)
        print 'Generated SQL:' + @newline + @query + @newline + @newline;
    end

    exec (@query);

对于我的测试表,这会生成查询:

select 
rtrim(rtrim(cast(id as nvarchar(max))) 
+ ',' 
+rtrim(cast(col0 as nvarchar(max))) 
+ ',' 
+rtrim(cast(col1 as nvarchar(max))) 
+ ',' 
+rtrim(cast(col2 as nvarchar(max))) 
+ ',' 
+rtrim(cast(col3 as nvarchar(max))) 
+ ',' 
+rtrim(cast(col4 as nvarchar(max))))  
as csvrow 
from test

和结果集:

csvrow
-------------------------------------------------------------------------------------------
EEE16C3A-036E-4524-A8B8-7CCD2E575519,alice,bob,charlie,dave,emily
F1EE6C84-D6D9-4621-97E6-AA8716C0643B,abby,bill,charlotte,daniel,evan

建议

  1. 修改光标循环以转义逗号
  2. 确保 @table_name 引用存储过程中的有效表 ( if object_id(@table_name) is null)
  3. 一些异常处理会很好
  4. 对此设置权限,以便只有运行报表的帐户才能执行它。动态 SQL 中的字符串连接可能是一个很大的安全漏洞,但我没有看到其他方法可以做到这一点。
  5. 确保游标关闭和释放的一些错误处理可能很好。

这可以用于任何不是表格的#temp表格。在这种情况下,您必须使用sys.objectsand sys.columnsfrom tempdb..

于 2012-12-05T17:17:15.973 回答
0

使用 SQL Server 的 XML 函数有一种奇特的方法,但是对于初学者,您可以将您关心的列的内容转换为 varchar 并用逗号连接它们吗?

SELECT cast(colA as varchar)+', '+cast(colB as varchar)+', '+cast(colC as varchar)
FROM table

请注意,如果您的任何内容中有逗号或双引号,这将被绊倒,在这种情况下,您还可以在每个演员表上使用替换功能来转义它们。

于 2012-12-04T17:37:54.360 回答
0
select STUFF((select ','+ convert(varchar,l.Subject) from tbl_Student B,tbl_StudentMarks L
where B.Id=L.Id FOR XML PATH('')),1,1,'') Subject FROM tbl_Student A where A.Id=10 
于 2013-02-20T10:20:06.050 回答
0

假设您知道表格有哪些列,并且您不想做一些动态和疯狂的事情,您可以这样做

SELECT CONCAT(ColumnA, ',', ColumnB) AS ColumnZ
FROM Table
于 2012-12-04T17:35:39.353 回答