【问题标题】:SQL Server returns Conversion failed error when using OPENJSON and JOIN使用 OPENJSON 和 JOIN 时 SQL Server 返回转换失败错误
【发布时间】:2021-05-20 14:49:58
【问题描述】:

我需要创建一个带有 JSON 输入参数的 SQL Server 存储过程。

我遵循了 Microsoft 的此文档:

我创建了以下存储过程,其中输入参数 @JsonIds 必须是存储在 NVARCHAR 数据类型变量中的 JSON 整数数组。

这是示例代码,与上面链接的文档中显示的非常相似:

CREATE OR ALTER PROCEDURE [MySP]
    @JsonIds NVARCHAR(200)  -- JSON Array of Ids.
AS
BEGIN

    IF (ISNULL(@JsonIds, 0) = 0 OR ISJSON(@JsonIds) = 0)
    BEGIN
        RAISERROR('Invalid JSON parameter.', 16, 1)
        RETURN
    END

    SELECT T.*
    FROM MyTable T
    INNER JOIN OPENJSON(@JsonIds) AS Ids ON T.Id = Ids.value;
END

但是当我像这样执行存储过程时:

EXEC [MySP] @JsonIds=N'[1,4]';

这是结果:

消息 245,级别 16,状态 1,过程 MySP,第 21 行 [批处理开始行 0]
将 nvarchar 值“[1,4]”转换为数据类型 int 时转换失败。

我不明白为什么它给了我转换错误。

环境

  • SQL Server 2017 v14.0.3356.20
  • SSMS v18.9.1

【问题讨论】:

  • json不应该以大括号开头和结尾吗? { & } - docs.microsoft.com/en-us/sql/t-sql/functions/…
  • 一个数组是有效的json。
  • @lptr 这是一个很好的观察。但是额外的括号是从哪里来的呢?给它一个答案。我将删除我的答案,因为从技术上讲,它应该即时转换,即使最好提前转换 IMO。
  • .. 就是这样,转换错误...。 IF (ISNULL(@JsonIds, 0) = 0
  • 如果你“习惯于”写这个,那就别写了——@x IS NULL OR @x = 0(如果适用,在这种情况下@x = 0当然需要省略)通常执行比ISNULL(@x, 0) = 0 更好,因为前者适合索引查找,而后者不适合。当然,在这种情况下,我们处理标量并不重要,但一般来说。

标签: arrays json sql-server stored-procedures


【解决方案1】:

如果您想坚持您的测试方法,您需要用引号将 0 括起来,因为它无法检查 nvarchar json 字符串是否等于 int。

IF (ISNULL(N'[1,4]', '0') = '0' OR ISJSON(N'[1,4]') = 0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2016-09-21
    相关资源
    最近更新 更多