经过大量搜索并将使用Web上的FOR XML和.nodes()命令转换结果集的非常优秀的技术拼凑起来之后,我能够创建这个单一的查询(不是存储过程),它将任何任意的SQL查询转换为JSON数组做了相当不错的工作。改进SQL Server查询以将任意表转换为JSON
该查询会将每个数据行编码为带逗号前导的单个JSON对象。 数据行被括号括起来,然后整个结果集将被导出到一个文件。
我想看看有没有人能看到改善其性能的方法?
下面是一个示例表查询:
declare @xd table (col1 varchar(max), col2 int, col3 real, colNull int)
insert into @xd
select '', null, null, null
UNION ALL select 'ItemA', 123, 123.123, null
UNION ALL select 'ItemB', 456, 456.456, null
UNION ALL select '7890', 789, 789.789, null
select '[{}'
UNION ALL
select ',{' + STUFF((
(select ','
+ '"' + r.value('local-name(.)', 'varchar(max)') + '":'
+ case when r.value('./@xsi:nil', 'varchar(max)') = 'true' then 'null'
when isnumeric(r.value('.', 'varchar(max)')) = 1
then r.value('.', 'varchar(max)')
else '"' + r.value('.', 'varchar(max)') + '"'
end
from rows.nodes('/row/*') as x(r) for xml path(''))
), 1, 1, '') + '}'
from (
-- Arbitrary query goes here, (fields go where t.* is, table where @xd t is)
select (select t.* for xml raw,type,elements XSINIL) rows
from @xd t
) xd
UNION ALL
select ']'
我最大的批判它,就是它的出奇的慢。
目前大约需要3点半~42,000行。
我的另一个大的批评是,它目前假设所有看起来像数字的东西都是数字。它不尝试发现列类型(至少我不确定它是否可以)。
最后一个小问题是,第一个数据行在前面会有一个逗号,在技术上它不应该。为了弥补这一点,它需要在第一行中启动JSON数组的空JSON对象。
其他的批评(最好是有解决方案的)被邀请,我唯一真正的限制是该解决方案在很多任意的SQL查询中可以重复使用,而无需明确标识列名。
我使用SQL Server 2012的
感谢,并给其他人喜欢我,谁一直在寻找一个广义SQL结果 - > JSON数组转换器,尽情享受!
虽然我很赞赏你的SQL福,我要问:为什么?真实世界中你需要这样做的场景是什么?我不想在这里消极,只是为什么你需要这个而感到困惑。 – 2013-02-14 00:03:12
在这种情况下,我正在寻找一种特别的方式来快速将结果集加载到NoSQL数据库(如CouchDB)中,而无需构建大量基础结构或将任何内容添加到我的生产SQL环境中。 Mongo,Couch等人。似乎使用JSON作为数据传输的通用语言。一旦进入NoSQL数据库,我们可以尝试对数据集进行切片和切块,以了解它们的性能。复制CouchDB数据库以在远程桌面,便携式计算机,智能手机等上创建本地存储库比管理SQL复制基础架构要容易得多。所以我们正在做一些尽职调查。 – 2013-02-14 00:30:10
让我们不要在这里被愚弄,大多数是通过搜索现有的SQL到JSON和SQL来找到键/值对的答案。是的,我把它放在一起,通过UNION ALL在它周围放置了一些括号,使用case语句来处理引号更聪明一点,并开始尝试使用XSINIL的东西(也许我甚至知道其中一些实际上是如何工作的; ))但我真的不能承认这一点。关于我最近做的唯一事情是将底部的子查询合并为一个XML数据集,然后让上层查询将其转换为键/值对。 – 2013-02-14 01:02:38