I am trying to rewrite a function to an inline Table Valued Fuction. Database is SQL Server 2022. Please have a look at the following SQL Fiddle. I tried multiple rewrites with explicit CASTs but it still wouldn't work for the key from the OPENJSON function. Running the query without that column however works as expected.
Can you please give any insight why this error occurs and how to fix it?
Thanks to @siggemannen for the solution: The collation of the key has to be changed as well.Here's a SQL Fiddle to show the working solution.
Here's the example as code:
DECLARE @json NVARCHAR(MAX) =N'{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Save", "onclick": "SaveDoc()"}
]
}
}} '
;
/* code adapted from Phil Factor
https://www.red-gate.com/simple-talk/databases/sql-server/t-sql-programming-sql-server/importing-json-web-services-applications-sql-server/
*/
WITH cteRecurseJSON AS
(
SELECT
CAST(1 AS INTEGER) AS Depth,
--CAST('$' AS NVARCHAR(4000)) AS ThePath,
CAST(N'' AS NVARCHAR(4000)) AS ThePath,
CAST(@json AS NVARCHAR(MAX)) AS TheValue,
CAST('object' AS VARCHAR(10)) AS ValueType
UNION ALL
SELECT
r.Depth+1 AS Depth,
CAST(v.[Key] AS NVARCHAR(4000)) AS ThePath,
Coalesce(Value,'') AS TheValue,
CAST(CASE Type WHEN 1 THEN 'string'
WHEN 0 THEN 'null'
WHEN 2 THEN 'int'
WHEN 3 THEN 'boolean'
WHEN 4 THEN 'array' ELSE 'object' END AS VARCHAR(10)) AS ValueType
FROM cteRecurseJSON r
CROSS APPLY OPENJSON(r.TheValue) v
WHERE r.ValueType IN ('array','object')
)
SELECT *
FROM cteRecurseJSON
1条答案
按热度按时间dgsult0t1#
The value
ThePath
in the anchor part needs to benvarchar(max)
and you need to change the collation as noted by @siggemanen.You should also use
STRING_ESCAPE
for correct escaping of paths. And you can simplify theCASE
by just checking for an array.db<>fiddle