OPENJSON不会select所有文件都变成SQLtable
OPENJSON does not select all documents into the SQL table
我一直在尝试将 JSON 文件的内容导出到 SQL 服务器 table。但是,尽管 JSON 中存在多行,但输出 SQL table 仅包含 JSON 的第一行。我使用的代码如下:
DROP TABLE IF EXISTS testingtable;
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT * INTO testingtable FROM OPENJSON(@json) WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5)
)
SELECT * FROM testingtable
并且得到的输出如下:
Click to view
字符串无效 JSON。 JSON 文档中不能有 两个 根对象。正确格式化后,JSON 字符串如下所示
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
应该是
DECLARE @json VARCHAR(MAX) = '[{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }
]';
看起来 OPENJSON 解析了第一个对象并在遇到无效文本时立即停止。
解决此问题的 快速而肮脏的 方法是添加缺少的方括号:
SELECT * FROM OPENJSON('[' + @json + ']') WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5))
我怀疑该字符串来自日志或事件文件,该文件将单独的记录存储在不同的行中。这是无效的,也没有任何类型的标准或规范(尽管有域名抢注者),但许多高流量应用程序使用它,例如在日志文件或事件流中。
他们这样做的原因是不需要构造或读取整个数组来获取记录。 很容易 只需为每条记录追加一个新行。读取大文件并并行处理它们也更容易 - 只需逐行读取文本并将其提供给工作人员。或者将文件分成 N 个部分到最近的换行符并将各个部分提供给不同的 机器 。这就是 Map-Reduce 的工作原理。
这就是为什么添加方括号是一种肮脏的解决方案 - 您必须先从数 MB 或 GB 大小的文件中读取整个文本,然后才能对其进行解析。这不是 OPENJSON 的目的。
正确的解决方案是使用另一个工具逐行读取文件,解析记录并将值插入目标表。
如果您知道 JSON 文档不会包含任何内部换行符,您可以使用 string_split 拆分字符串。 OPENJSON 不关心前导空格或尾随 ,
。这样您就可以避免添加 [
]
字符,并且不必将其解析为一个大文档。
EG:
DROP TABLE IF EXISTS testingtable;
DECLARE @jsonFragment VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT *
INTO testingtable
FROM string_split(@jsonFragment,CHAR(10)) docs
cross apply
(
select *
from openjson(docs.value)
WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5))
) d
SELECT * FROM testingtable
您可以将此格式称为 "JSON Fragment",类似于 XML。这是 XML 和 JSON 在 SQL Server 中的另一个区别。对于 XML 引擎乐于解析和存储 XML 片段,但不支持 JSON.
多行 JSON 文本用方括号括起来,例如;
[
{first data set},
{second data set}, .....
]
您可以在将数据传递给此查询时添加方括号,或者您可以将方括号添加到 @json 变量(例如 '['+ @json + ']')
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT * INTO testingtable FROM OPENJSON ('['+ @json + ']') WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5)
)
SELECT * FROM testingtable
我一直在尝试将 JSON 文件的内容导出到 SQL 服务器 table。但是,尽管 JSON 中存在多行,但输出 SQL table 仅包含 JSON 的第一行。我使用的代码如下:
DROP TABLE IF EXISTS testingtable;
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT * INTO testingtable FROM OPENJSON(@json) WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5)
)
SELECT * FROM testingtable
并且得到的输出如下: Click to view
字符串无效 JSON。 JSON 文档中不能有 两个 根对象。正确格式化后,JSON 字符串如下所示
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
应该是
DECLARE @json VARCHAR(MAX) = '[{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }
]';
看起来 OPENJSON 解析了第一个对象并在遇到无效文本时立即停止。
解决此问题的 快速而肮脏的 方法是添加缺少的方括号:
SELECT * FROM OPENJSON('[' + @json + ']') WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5))
我怀疑该字符串来自日志或事件文件,该文件将单独的记录存储在不同的行中。这是无效的,也没有任何类型的标准或规范(尽管有域名抢注者),但许多高流量应用程序使用它,例如在日志文件或事件流中。
他们这样做的原因是不需要构造或读取整个数组来获取记录。 很容易 只需为每条记录追加一个新行。读取大文件并并行处理它们也更容易 - 只需逐行读取文本并将其提供给工作人员。或者将文件分成 N 个部分到最近的换行符并将各个部分提供给不同的 机器 。这就是 Map-Reduce 的工作原理。
这就是为什么添加方括号是一种肮脏的解决方案 - 您必须先从数 MB 或 GB 大小的文件中读取整个文本,然后才能对其进行解析。这不是 OPENJSON 的目的。
正确的解决方案是使用另一个工具逐行读取文件,解析记录并将值插入目标表。
如果您知道 JSON 文档不会包含任何内部换行符,您可以使用 string_split 拆分字符串。 OPENJSON 不关心前导空格或尾随 ,
。这样您就可以避免添加 [
]
字符,并且不必将其解析为一个大文档。
EG:
DROP TABLE IF EXISTS testingtable;
DECLARE @jsonFragment VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT *
INTO testingtable
FROM string_split(@jsonFragment,CHAR(10)) docs
cross apply
(
select *
from openjson(docs.value)
WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5))
) d
SELECT * FROM testingtable
您可以将此格式称为 "JSON Fragment",类似于 XML。这是 XML 和 JSON 在 SQL Server 中的另一个区别。对于 XML 引擎乐于解析和存储 XML 片段,但不支持 JSON.
多行 JSON 文本用方括号括起来,例如;
[
{first data set},
{second data set}, .....
]
您可以在将数据传递给此查询时添加方括号,或者您可以将方括号添加到 @json 变量(例如 '['+ @json + ']')
DECLARE @json VARCHAR(MAX) = '{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" },
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }';
SELECT * INTO testingtable FROM OPENJSON ('['+ @json + ']') WITH (_id int, city varchar(20), loc float(50), pop int, state varchar(5)
)
SELECT * FROM testingtable