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