2

これが可能かどうか興味があります。

私はテーブルを持っているか、これはデータを含む古いテーブルに固有のものである可能性があります。単純な SELECT は、列と行を結果セットとして返します。行を返すことができるかどうかを調べようとしていますが、列ではなく、列が連結され、カンマで区切られています。そのため、期待される行数が返されましたが、CSV ファイルと同様に、すべての列のカンマ区切りの結果を保持する varchar 列は 1 つだけでした。

ありがとう。

[アップデート]

ここで、私が尋ねている理由をもう少し詳しく説明します。クライアントでこれを行うオプションはありません。これは、SSIS で実行しようとしているタスクです。

シナリオ: SSIS で動的に作成されるテーブルがありますが、作成されるたびに列名が変わります。元のパッケージは BCP を使用してデータを取得し、それをフラット ファイルに配置しますが、ジョブ BCP を実行するときの権限により、必要な宛先にフラット ファイルを作成できません。これも変更できません。

もう 1 つの問題は、SSIS 2005 では、フラット ファイルの変換先を使用して、入力ソースから列名をマップする必要があることです。列名が変化し続けるため、これを行うことはできません。

元のテーブルからすべてのデータを取得し、ストリーム ライターを使用して CSV に書き込むスクリプト タスクを作成しましたが、各行をループしてから各列をループして、すべての列で構築された文字列を生成する必要があります。vb.net を使用した厄介なループに対して、SQL サーバー上のこの列の連結のパフォーマンスを測定したいと考えています。

行ごとに 1 つの列を生成するように SQL を取得できれば、行を構築するために各列を反復処理する代わりに、テキスト ファイルに 1 行を書き込むだけで済みます。

4

5 に答える 5

1

私はあなたがこれを試してみるべきだと思います

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

これは一部クリーンアップされる可能性がありますが、動的SQLに格納さsys.objectsれているメタデータを使用してこれを行うことができます。sys.columns私は動的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がsprocif object_id(@table_name) is null内の有効なテーブル()を参照していることを確認してください
  3. いくつかの例外処理は良いでしょう
  4. レポートを実行するアカウントのみがレポートを実行できるように、これに権限を設定します。動的SQLでの文字列の連結は、大きなセキュリティホールになる可能性がありますが、これを行う別の方法はありません。
  5. カーソルを閉じて割り当てを解除するためのエラー処理が役立つ場合があります。

これは、テーブルではないすべてのテーブルに使用でき#tempます。その場合は、とを使用する必要がsys.objectsありsys.columnsますtempdb..

于 2012-12-05T17:17:15.973 に答える
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 に答える
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 に答える