我有一个表列表,我最终想要构建一些看起来像这样的JSON:
{
"Table1": [
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" }
],
"Table2": [
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" }
],
"Table3": [
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" },
{ "col1": "value", "col2": "value" }
]
}
创建JSON对我来说不是问题(虽然我不能在SQL Server 2014上使用FOR JSON
),我甚至对SQL有一个简单的实现:
declare @tables table (
tabname varchar(100)
)
insert into @tables(tabname)
select 'Table1' union all
select 'Table2' union all
select 'Table3'
/* Master dataset */
select tabname from @tables
declare tabcur cursor for select tabname from @tables
open tabcur
declare @tabname varchar(100)
fetch tabcur into @tabname
while @@FETCH_STATUS = 0
begin
/* Detail dataset */
execute ('select * from [' + @tabname + ']')
fetch tabcur into @tabname
end
close tabcur
deallocate tabcur
这背后的想法是我得到一个表的列表作为主数据集,并且对于每一行我也得到一个细节数据集。我可以按索引匹配,或者通过将表名添加到详细数据集来消除主数据集。
无论哪种方法都有效。但我的实际列表包含724个表,性能很差。
然后我将其更改为构建union all
语句的SQL字符串,并仅在释放游标后执行该字符串。这主要解决了我的性能问题。
但它似乎仍然是一种非常九十年代的做法。有了SQL Server从那时起添加的所有有趣的东西,我认为必须有一个更简单的方法。我基本上希望使用主数据集作为第二个数据集的输入,该数据集包含来自所有表的行(我感兴趣的列在所有表中都是相同的,因此它们将作为一个结果集工作)
我的下一次尝试是创建一个接受表名作为参数并返回结果集的函数。我以为我可以交叉申请:
select tabname, result.col1, result.col2
from @tables
cross apply dbo.SelectFromTable(@tables.tabname) result
但这仍然是死产,因为SQL Server不允许在函数中使用动态SQL。
在没有光标的情况下,有没有一种表现良好的方法呢?
答案 0 :(得分:1)
它不漂亮而你 真的 应该看一个不同的设计,但是如果你这样做是困难的,你可以避免使用cursor
for xml
(用于将所有行放入一个分隔列)和stuff
(用于删除前导分隔符,在本例中为' union all '
:
declare @tables table (
tabname varchar(100)
);
insert into @tables(tabname)
select 'Table1' union all
select 'Table2' union all
select 'Table3';
select stuff((select ' union all select * from [' + tabname + ']'
from @tables
for xml path('')
)
,1,11,'') as query
哪个输出:
select * from [Table1] union all select * from [Table2] union all select * from [Table3]