因此,假设我在具有某种结构的表中有一个varchar列:
{
"Response":{
"DataArray":[
{
"Type":"Address",
"Value":"123 Fake St"
},
{
"Type":"Name",
"Value":"John Doe"
}
]
}
}
我想在“ DataArray”数组元素的“ Value”字段上创建一个持久的计算列,该字段包含一个等于“ Name”的Type字段。 (我希望我能正确解释。基本上,我想在该结构上索引人物姓名。)
问题在于,与其他json对象不同,我无法直接使用JSON_VALUE
函数来提取所述值。我不知道是否可以做到这一点,我一直在摸索JSON_QUERY
,但到目前为止我还不知道该怎么办。
任何想法和帮助表示赞赏。谢谢!
答案 0 :(得分:5)
您可以使用以下功能来实现它:
CREATE FUNCTION dbo.my_func(@s NVARCHAR(MAX))
RETURNS NVARCHAR(100)
WITH SCHEMABINDING
AS
BEGIN
DECLARE @r NVARCHAR(100);
SELECT @r = Value
FROM OPENJSON(@s,'$.Response.DataArray')
WITH ([Type] NVARCHAR(100) '$.Type', [Value] NVARCHAR(100) '$.Value')
WHERE [Type] = 'Name';
RETURN @r;
END;
定义表:
CREATE TABLE tab(
val NVARCHAR(MAX) CHECK (ISJSON(val) = 1),
col1 AS dbo.my_func(val) PERSISTED -- calculated column
);
样本数据:
INSERT INTO tab(val) VALUES (N'{
"Response":{
"DataArray":[
{
"Type":"Address",
"Value":"123 Fake St"
},
{
"Type":"Name",
"Value":"John Doe"
}
]
}
}');
CREATE INDEX idx ON tab(col1); -- creating index on calculated column
SELECT * FROM tab;
答案 1 :(得分:2)
您可以将计算列与PATINDEX一起使用,并为其编制索引:
std::uintptr_t
答案 2 :(得分:1)
您可以使用@Lukasz Szozda发布的标量函数-这是一个很好的解决方案。 但是,计算列中的T-SQL标量UDF的问题在于它们会破坏表所涉及的任何查询的性能。不仅数据修改(插入,更新,删除)会减慢速度,而且查询的任何执行计划也会涉及该表不能利用并行执行计划。 即使在查询中未引用计算列的情况下,也是如此 。甚至索引构建也失去了利用并行执行计划的能力。请注意本文:Another reason why scalar functions in computed columns is a bad idea,作者Erik Darling。
这不是那么漂亮,但是,如果性能很重要,那么它将获得所需的结果,而没有标量UDF的缺点。
CREATE TABLE dbo.jsonStrings
(
jsonString VARCHAR(8000) NOT NULL,
nameTxt AS (
SUBSTRING(
SUBSTRING(jsonString,
CHARINDEX('"Value":"',jsonString,
CHARINDEX('"Type":"Name",',jsonString,
CHARINDEX('"DataArray":[',jsonString)+12))+9,8000),1,
CHARINDEX('"',
SUBSTRING(jsonString,
CHARINDEX('"Value":"',jsonString,
CHARINDEX('"Type":"Name",',jsonString,
CHARINDEX('"DataArray":[',jsonString)+12))+9,8000))-1)) PERSISTED
);
INSERT dbo.jsonStrings(jsonString)
VALUES
('{
"Response":{
"DataArray":[
{
"Type":"Address",
"Value":"123 Fake St"
},
{
"Type":"Name",
"Value":"John Doe"
}
]
}
}');
请注意,这对于您发布的结构非常有效。可能需要根据JSON的功能和外观进行调整。
第二种(也是更好但更复杂)的解决方案是从Lukasz Szozda的标量UDF中获取json路径逻辑,并将其放入CLR中。如果正确编写T-SQL标量UDF,则不会出现T-SQL标量UDF所存在的上述问题。