Как выполнить две функции в соответствии с результатом таблицы с условием с помощью mssql? - PullRequest
0 голосов
/ 11 марта 2019

ParseValuesJson и insertToTable - определяемые пользователем функции.

Ниже приведен результат выполнения (ParseValuesJson):

declare 
    @json nvarchar(max)=N'{
    "Book":{
        "IssueDate":"02-15-2019"
        , "Detail":{
            "Type":"Any Type"
            , "Author":{
                "Name":"Annie"
                , "Sex":"Female"
            }
        }
        , "Chapter":[
            {
                "Section":"1.1"
                , "Title":"Hello world."
            }
            ,
            {
                "Section":"1.2"
                , "Title":"Be happy."
            }       
        ]
        , "Sponsor":["A","B","C"]
    }
}'

declare 
    @tempTable table (
        topKey nvarchar(4000)
        , [key] nvarchar(4000)
        , IsType bit
        , IsList bit
        , [value] nvarchar(4000))

--execute
insert @tempTable  
select * from GetValuesJson(@json,default)
topKey  Key         isType  isList  Value
--
Book    Type        0       0       Any Type
Book    Author      1       0       {"Name":"Annie", "Sex":"Female"}
Book    IssueDate   0       0       02-15-2019
Book    Chapter     1       1       [{"Section":"1.1", "Title":"Hello world."}, {"Section":"1.2", "Title":"Be happy."}]
Book    Sponsor     1       1       ["A","B","C"]

Как заголовок, если игнорировать то, что делает функция, как я могу достичь следующей цели?

Если IsType = 1, я хочу вызвать функцию ParseValuesJson; Если IsType = 0, я хочу вызвать функцию insertToTable.

Но я обнаружил, что sql case не может так использоваться.

Этот SQL-запрос может выполняться рекурсивно и вызывать разные функции соответственно на одном уровне.

Это означает, что я не могу сначала проанализировать всю строку (ParseValuesJson), а затем вставить результат (insertToTable) в таблицу.

Есть ли другой способ достичь?

select 
    case IsType when 1 then
        ParseValuesJson('{"' + [key] + '":' + [value] + '}',IsList)
    else
        insertToTable(topKey,[key])
    end
from ParseValuesJson(@json,default)

concept

1 Ответ

0 голосов
/ 11 марта 2019

Что ж, проще всего сделать это разделить его на два отдельных элемента SELECT.

select ParseValuesJson('{"' + [key] + '":' + [value] + '}',IsList)
from ParseValuesJson(@json,default)
where IsType = 1


select insertToTable(topKey,[key])
from ParseValuesJson(@json,default)
where IsType = 0

Но я думаю, что этот подход не поможет вам, поскольку внутри пользовательских функций вы не можете использовать операторы INSERT, UPDATE, DELETE -> т.е. изменять данные таблицы

Так что я думаю, что для анализа JSON вам потребуется пользовательский рекурсивный CTE, чтобы сначала проанализировать все значения, а затем сразу вставить их в временную таблицу.

Примерно так:

;WITH ParsedJSON(topKey, [key], IsType, IsList, [value])
AS
(
SELECT topKey, [key], IsType, IsList, [value]
FROM ParseValuesJson('{"' + [key] + '":' + [value] + '}',IsList)

UNION ALL

SELECT topKey, [key], IsType, IsList, [value]
FROM ParsedJSON
WHERE IsType = 1
) 
insert @tempTable  
select * from ParsedJSON
...