Json 基于条件创建SQL视图

Json 基于条件创建SQL视图,json,sql-server,sql-view,Json,Sql Server,Sql View,我试图找出如何从一个表中创建一个sql视图,该表的一列包含字符串和json格式(它的数据类型为varchar)。某些行中的列仅包含字符(,例如32564),而其他行中包含json数据。如何基于此列创建一个视图,如果column1中存储了json,那么: create view dbo.vTable1 select ... from dbo.Table1 cross apply openjson(...) with (...) cross apply openjson(...) with (..

我试图找出如何从一个表中创建一个sql视图,该表的一列包含字符串和json格式(它的数据类型为
varchar
)。某些行中的列仅包含字符(
,例如32564
),而其他行中包含json数据。如何基于此列创建一个视图,如果column1中存储了json,那么:

create view dbo.vTable1
select 
...
from dbo.Table1
cross apply openjson(...) with (...)
cross apply openjson(...) with (...)
否则:

create view dbo.vTable2
select 
...
from dbo.Table1

(我不想使用存储过程)

这里是根据注释编译的解决方案

样本数据

create table data
(
  id int,
  value nvarchar(100)
);

insert into data (id, value) values
(1,
'{
  "Key1": 100,
  "Key2": "One hundred"
}'),
(2,
'{
  "Key1": 200,
  "Key2": "Two hundred"
}'),
(3, '300'),
(4, '400'),
(5, 'Five hundred'),
(6, 'Six hundred');
解决方案1

id  result
--  ------
1   100
2   200
3   300
4   400
如果您想返回数字数据

create view idNumberView as
select d.id,
       jv.result
from data d
cross apply openjson(d.value) with (result int '$."Key1"') jv
where isjson(d.value) = 1
  union all
select d.id,
       convert(int, d.value)
from data d
where try_convert(int, d.value) is not null;
结果1

id  result
--  ------
1   100
2   200
3   300
4   400
解决方案2

id  result
--  ------------
1   One hundred
2   Two hundred
5   Five hundred
6   Six hundred
如果要返回字符串数据

create view idStringView as
select d.id,
       jv.result
from data d
cross apply openjson(d.value) with (result nvarchar(20) '$."Key2"') jv
where isjson(d.value) = 1
  union all
select d.id,
       d.value
from data d
where try_convert(int, d.value) is null
  and isjson(d.value) = 0;
结果2

id  result
--  ------------
1   One hundred
2   Two hundred
5   Five hundred
6   Six hundred

查看这两种解决方案的运行情况。

“某些行中的此列仅包含数字(例如32564),而其他行中包含json。”听起来您的数据已非规范化,需要修复的是该表。如果列同时包含JSON数据和“数值”,则后者根据定义不能是数值<代码>'32454'不是数字,而是字符串。修改设计,那么你就不需要了没有问题。我同意@Larnu。但是,请检查ISNUMERIC函数。这可能会有帮助@GrantFritchey
ISNUMERIC
充其量是一个有缺陷的函数<代码>尝试转换将是一个更好的选择。尤其是OP希望将数据作为数值使用,而不是字符串使用(因此不会得到像
'40'
这样的值大于
'32564'
)的结果);这是个问题<代码>'32564'不是数字,而是字符串。如果需要存储数字,则使用数字数据类型;也许
int
。不要在单个列中混合数据类型。修正设计,修正问题。