Escaping characters in T-SQL OPENJSON queries - sql

I have the following JSON Data
DECLARE #jsonData NVARCHAR(MAX)
SET #jsonData =
'{
"insertions":[
{
"id":"58735A79-DEA8-462B-B3EB-C2797CA9D44E",
"last-modified":"2017-08-08 13:07:32",
"label":"HelloWorld1"
},
{
"id":"00565BCD-4240-46CF-A48F-849CB5A8114F",
"last-modified":"2017-08-08 13:11:38",
"label":"HelloWorld12"
}
]
}'
And trying to perform a select from it:
SELECT
*
FROM
OPENJSON(JSON_QUERY(#jsonData,'$.insertions'))
WITH
(uuid UNIQUEIDENTIFIER '$.id',
modified DATETIME '$.last-modified',
Label NVARCHAR(128) '$.label'
)
It doesn't like the dash in the last-modified field.
Msg 13607, Level 16, State 4, Line 18
JSON path is not properly formatted. Unexpected character '-' is found at position 6.
Is there a way to escape the dash in the query? Everything works fine if there is no dash.
As required to support JSON, I'm using SQL Server 2016 with compatibility level = 130

Adding double quotes around the field name seems to work
SELECT
*
FROM
OPENJSON(JSON_QUERY(#jsonData,'$.insertions'))
WITH
(uuid UNIQUEIDENTIFIER '$.id',
modified DATETIME '$."last-modified"',
Label NVARCHAR(128) '$.label'
)

Related

Conversion failed when converting the nvarchar value to data type int sql server

I have a table. There is data in this table and there is a checkbox next to each data. Multiple selection is possible. After the user makes a selection, the id numbers of the selected columns are come in the array. I convert the array to string and send it to the stored procedure and I run the following stored procedure:
Example value for #ResultsIds: 65, 66, 67, 68, 125
#ResultsIds nvarchar(250)
UPDATE MyTable SET [IsVerified] = 1 WHERE Id IN (#ResultsIds)
And I got this error:
Conversion failed when converting the nvarchar value '65, 66, 67, 68, 125' to data type int. Because [Id] column is int data type.
I tried CAST and CONVERT functions of SQL but it didn't work.
SQL Server doesn't do that automatically. Assuming you're on a recent version, you can do this:
declare #ResultsIds nvarchar(250) = '65,66,67,68,125'
UPDATE MyTable
SET [IsVerified] = 1
WHERE Id IN (
select [value]
from string_split(#ResultIDs, ',')
)
declare #ResultsIds nvarchar(250)='65,66,67,68,125'
UPDATE MyTable SET [IsVerified] = 1 WHERE cast(Id as varchar) IN (#ResultsIds)
I solved problem using foreach. I separated the numbers in the string from commas and transferred each number to the array. Then I updated the array one by one by running foreach loop.
public void Verify(DB db, string rows)
{
int[] nums = Array.ConvertAll(rows.Split(','), int.Parse);
foreach (int value in nums)
{
DbCommand cmd = db.GetStoredProcCommand("VerifyProcess");
db.AddInParameter(cmd, "#ResultId", DbType.Int32, value);
db.ExecuteNonQuery(cmd);
}
}

Parsing JSON text through ADF into SQL with "legitimate" escape characters in the string

I am using ADF to access an API, the response is added to a single column in a SQL table. The json_response is then transformed into columns and rows. However, in the JSON response there are characters such as " or : or ' or < { } = ? etc that the product owner claims should legitimately be there.
And example of part the json response is:
"Name": "Registration: Update for renewal on Premises",
or
"Name": "Harry Potter "{}<>+?"
How can I process the JSON into SQL where it would process these responses. I recognise that in the 2nd example, other than replace(XXX,'"{}<>+','') for every instance there may be a better suggestion.
The error message I receive is "JSON text is not properly formatted. Unexpected character ':' is found at position XX"
The SQL script I have essentially is:
DECLARE #STRING VARCHAR(MAX) = 'declare #Var VARCHAR(MAX) select #Var = JsonResponse from dbo.JsonResponse SELECT '
SET #STRING = #STRING + 'JSON_VALUE(value,''$.' + #ColKey + ''') as ' + #ColName + IIF(#CNT = #MAX, #Audit + ' from openjson(#Var) ',',')
This script works as planned AS LONG as the data is clean.
Thankyou, I am using ADF and Microsoft SQL Azure (RTM) - 12.0.2000.8

Control characters handling in XML

I am following XML based transport of data using FOR XML AUTO. When a column containing control character was encountered and a XML transform as below was attempted, it resulted in an exception:
DECLARE #TrialData NVARCHAR(200) = ''; --Not empty string..contains a control character '<-'
DECLARE #TrialDataInHex VARBINARY(100)
SET #TrialDataInHex = CONVERT(VARBINARY(100),#TrialData)
SELECT #TrialDataInHex; -- returns 0x1B00 looks like this '<-'
Now, when I try to insert the same into XML variable like below
DECLARE #a_XML XML;
SET #a_XML = #TrialData;
This resulted in
XML parsing: line 0, character 0, unrecognized input signature
Can Anyone suggest how control characters are usually handled when XML FROM SQL data medium is used?
You have to wrap that value in an XML element:
XMLELEMENT("TrialData" , #TrialData)
generates
<TrialData>←</TrialData>

cast text to xml error illegal qualified name character

how to fix error illegal qualified name character in this sample :
Declare #Str As nvarchar(256)
Set #Str = N'<Log "ReceiptStockHNo="2" ReceiptStockHDate="Feb 4 2" Comment="" />'
Select Cast(#Str As xml)
Error :
Msg 9455, Level 16, State 1, Line 5
XML parsing: line 1, character 6, illegal qualified name character
What is this extra " ? .
Remove the " and it will work.
Additional information :
To prevent future errors for needed encoded characters like & , < , use the appropriate replacement :
Declare #Str As nvarchar(256)
Set #Str = '<tag>&</tag>'
Select Cast(#Str As xml)
Will yield :
Msg 9421, Level 16, State 1, Line 3 XML parsing: line 1, character 7
illegal name character
While changing < to < :
Declare #Str As nvarchar(256)
Set #Str = '<tag><</tag>'
Select Cast(#Str As xml)
Will be Ok.

SQL: Parse JSON

Using SQL, how can I select the value for "conversion_event" from the JSON below?
{"str":[1,1342886173,100000627571405,"offsite_conversion.lead",{"action.type":"offsite_conversion","conversion_event":387756207950188,"tag":"lead"},["conversion_event"],[],{"amount":12623486},"1:11:1:0:0:1:0"]}
There are some unusual things in here, for example JSON within JSON, and the square brackets. Assume that lengths of all values vary by row, so you cannot slice by a set number of character positions.
Based on comments:
declare #astr varchar(max);
declare #start int;
declare #end int;
set #astr = '{"str":[1,1342886173,100000627571405,"offsite_conversion.lead",{"action.type":"offsite_conversion","conversion_event":387756207950188,"tag":"lead"},["conversion_event"],[],{"amount":12623486},"1:11:1:0:0:1:0"]}';
select #start = charindex('"conversion_event":',#astr)
select #end = charindex(',"tag":',#astr)
select substring(#astr,#start,#end-#start);
returns
"conversion_event":387756207950188
add
set #start = #start + 19;
to get just the number.
SELECT substring('{"str":[1,1342886173,100000627571405,"offsite_conversion.lead",{"action.type":"offsite_conversion","conversion_event":387756207950188,"tag":"lead"},["conversion_event"],[],{"amount":12623486},"1:11:1:0:0:1:0"]}',
101,16);
or
select substring('{"str":[1,1342886173,100000627571405,"offsite_conversion.lead",{"action.type":"offsite_conversion","conversion_event":387756207950188,"tag":"lead"},["conversion_event"],[],{"amount":12623486},"1:11:1:0:0:1:0"]}',
151,16)
Ok this is the structure of the object:
{
"str":[1,
1173,
10005,
"offsite_conversion.lead",
{"action.type":"offsite_conversion",
"conversion_event":387756207950188,
"tag":"lead"},
["conversion_event"],
[],
{"amount":14486},
"1:11:1:0:0:1:0"
]}
An object with an atribute str which is an array.
The 5th element has a 2nd attribute conversion event
The 6th element is an array of one element which is conversion event.
So the question is... is this structure the same and which of these do you want?