首页 > 解决方案 > 来自 OPENJONS() 的 TSQL 具有显式架构:十进制 (38,30) 数据类型中的空字符串

问题描述

当它是空字符串时,我无法from openjson()转换、转换或识别数据类型。decimal(38,30)出于某种原因,我必须将其明确声明为varchar(39). 为什么? 否则,我会收到错误消息,Error converting data type varchar to numeric我将进一步解释:

我最终构建了一个 UPDATE 语句,但我已经简化了这个 SO question 中显示的示例。这个临时表对应于我真正的目标表;数据类型是准确的。

declare @tmpSchedules table (
    [EffectDate] [smalldatetime] null,
    [Description] [varchar](30) null,
    [Calculated] [bit] not null,
    [BaseSchedule] [varchar](9) null,
    [Factor] [decimal](38, 30) null
    )

这是我的传入数据。这是一个 JSON 字符串。请注意,因子可能是:1) 结构中完全缺失,2) 空字符串,或 3)decimal(38,30)值。

declare @jsonRequest nvarchar(max) =
'{
    "EffectDate": "2021-04-01",
    "Description": "",
    "Calculated": "",
    "Factor": "",
    "BaseSchedule": null
}'

/*
        ==FACTORS==

NULL (missing from structure)     --->>> from openjson() can handle this

"Factor": "",     --->>> from openjson() CAN NOT handle this!!!

"Factor": "0.411334674542662787386271222800",     --->>> from openjson() can handle this

*/

当我将它声明为 adecimal时,它不能是空字符串,否则我会得到这个: Error converting data type varchar to numeric。由于它是decimal,我想将其声明为小数。我不想将其声明为varchar!

另外,我需要选择NULL它是空字符串还是实际上为空:nullif(Factor, '') as Factor

无论如何,我对json_value()and的运气更好json_query(),所以也许我应该改变我的策略?

问题是我对 的错误期望from openjson(),还是这是转换/转换/数据类型问题?

select
    EffectDate
    ,Description
    ,Calculated
    ,BaseSchedule
    ,Factor
    --,nullif(Factor, '') as Factor
from openjson(@jsonRequest, '$')
with
(
    EffectDate [smalldatetime] '$.EffectDate'
    ,Description [varchar](30) '$.Description'
    ,Calculated [bit] '$.Calculated'
    ,BaseSchedule [varchar](9) '$.BaseSchedule'
    ,Factor [decimal](38, 30) '$.Factor' --Error converting data type varchar to numeric.
    --,Factor [varchar](39) '$.Factor'

)

标签: jsonsql-server

解决方案


在这里,我们使用字符串FACTOR,然后try_convert将其转换为小数。这样空值不会失败

例子

declare @jsonRequest nvarchar(max) =
'{
    "EffectDate": "2021-04-01",
    "Description": "",
    "Calculated": "",
    "Factor": "0.411334674542662787386271222800",
    "BaseSchedule": null
}'


select
    EffectDate
    ,Description
    ,Calculated
    ,BaseSchedule
    ,Factor  = try_convert(decimal(38,30),Factor)    --<<< Notice the try_convert()
from openjson(@jsonRequest, '$')
with
(
    EffectDate [smalldatetime] '$.EffectDate'
    ,Description [varchar](30) '$.Description'
    ,Calculated [bit] '$.Calculated'
    ,BaseSchedule [varchar](9) '$.BaseSchedule'
    ,Factor [varchar](39) '$.Factor'
)

退货

EffectDate              Description Calculated  BaseSchedule    Factor
2021-04-01 00:00:00                 0           NULL            0.411334674542662787386271222800

推荐阅读