這可能會被清除一些,但您可以通過使用存儲在sys.objects
和sys.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('[email protected]+' 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('[email protected]+') as csvrow from '[email protected]_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是指在存儲過程有效的表(
if object_id(@table_name) is null
)
- 有些異常處理將是一件好事
- 在此設置權限,以便只有運行報表的帳戶才能執行該權限。動態SQL中的字符串串聯可能是一個很大的安全漏洞,但我沒有看到另一種方法來做到這一點。
- 一些錯誤處理,以確保光標被關閉和釋放可能是很好的。
這可以用於任何不是#temp
表的表。在這種情況下,您必須使用tempdb..
中的sys.objects
和sys.columns
。
請張貼一些示例數據,然後期望的結果。 – Taryn
在客戶端上做這種事情會更有意義。在服務器上做這件事的基本原理是什麼? –
@bluefeet這將適用於任何表格。 – PaulHR