Ошибка при использовании CONVERT при выборе из OPENJSON - PullRequest
2 голосов
/ 08 апреля 2019

Учитывая переменную @PartsData, которая является VARCHAR(MAX) и содержит набор данных json, этот запрос работает нормально:

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

Но, предположим, я хочу преобразовать некоторые данные при открытии из Джейсона:

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

На это я получаю:

Неверный синтаксис рядом с ключевым словом «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

1 Ответ

1 голос
/ 08 апреля 2019

Предложение WITH не является подходящим местом для этого, но вы можете использовать CROSS APPLY для вычисления необходимого значения для строк и использовать это значение в соединении. Что-то в этом примере:

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 (как я делал выше) самостоятельно. Добавьте пример данных и ожидаемый результат. Добавьте свои собственные попытки и объясните, почему ваш результат не полностью соответствует вашим потребностям. В этом поможет гораздо больше тысячи слов ...

UPDATE

Вы также можете извлечь производную таблицу из данных JSON, как здесь:

  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, подзапросы, применения или даже временные таблицы. Какой из них лучше для вас, зависит от количества строк и ваших потребностей ...

...