从 OPENJSON 进行选择时使用 CONVERT 时出错

Error when using CONVERT while SELECTing from OPENJSON

给定一个 @PartsData 变量 VARCHAR(MAX) 并包含一组 json 数据,此查询工作正常:

SELECT 
       *
FROM OPENJSON(@PartsData)
        WITH (
            PartId INT 'strict $.PartId', 
            ....
            CultureName VARCHAR(3) '$.CultureName',
            PartDescription VARCHAR(2000) '$.PartDescription'
        ) A

但是,假设我想在从 jason 打开数据时转换一些数据:

SELECT 
       *
FROM OPENJSON(@PartsData)
        WITH (
            PartId INT 'strict $.PartId', 
            ....
            CultureName VARCHAR(3) '$.CultureName',
            PartDescription VARCHAR(2000) '$.PartDescription'
            PhraseHash UNIQUEIDENTIFIER CONVERT([uniqueidentifier],hashbytes('MD2',concat('$.PartDescription', '$.CultureName'))
        ) A

关于这个,我得到:

Incorrect syntax near the keyword 'CONVERT'.

这没问题,但我需要原始 WITH 中的计算值,所以我可以加入它:

SELECT 
       *
       , CONVERT([uniqueidentifier],hashbytes('MD2',concat(CAST(A.PartDescription as NVARCHAR(max)),A.CultureName))) AS PhraseHash
FROM OPENJSON(@PartsData)
        WITH (
            PartId INT 'strict $.PartId', 
            ....
            CultureName VARCHAR(3) '$.CultureName',
            PartDescription VARCHAR(2000) '$.PartDescription'
        ) A

WITH-子句不适合这样做,但您可以使用 CROSS APPLY 计算所需的值 row wise 并使用连接中的这个值。此示例中的内容:

DECLARE  @tbl TABLE(ID INT,SomeValue VARCHAR(100));
INSERT INTO @tbl VALUES
 (1020,'Values 10 and 20')
,(2030,'Values 20 and 30');

DECLARE @json NVARCHAR(MAX)=
N'{
    "rows":
     [{"id":"1","val1":"10","val2":"20"},
      {"id":"2","val1":"20","val2":"30"},
      {"id":"3","val1":"20","val2":"30"},
      {"id":"4","val1":"40","val2":"30"}
    ]
  }';

  SELECT *
  FROM OPENJSON(@json,'$.rows')
  WITH(id INT,val1 NVARCHAR(10),val2 NVARCHAR(10)) A
  CROSS APPLY(SELECT CAST(CONCAT(A.val1,A.val2) AS INT)) B(ConcatenatedAndCasted)
  INNER JOIN @tbl t ON t.ID=B.ConcatenatedAndCasted;

对于你的下一个问题:请尝试自己设置一个 MCVE(就像我上面所做的那样)。添加示例数据和预期输出。添加您自己的尝试并解释为什么您的输出不能满足您的需求。这将帮助超过一千个字...

更新

您也可以从您的 JSON 数据中检索派生的 table,如下所示:

  WITH JSON_Data AS
  (
  SELECT *
  FROM OPENJSON(@json,'$.rows')
  WITH(id INT,val1 NVARCHAR(10),val2 NVARCHAR(10)) A
  )
  SELECT * FROM  @tbl t
  INNER JOIN JSON_Data jd ON t.ID=CAST(CONCAT(jd.val1,jd.val2) AS INT);

事实上,有多种使用 CTE、子查询、应用甚至临时 table 的方法。哪一个最适合您,取决于行数和您的需求...