I am trying to manipulate a JSON with a single quote inside, and I am having some troubles:
1.- When I have a function, I cant pass as parameter a JSON string with a single quote inside:
This is the function:
CREATE OR REPLACE FUNCTION public.give_me_text
(
IN text json
)
RETURNS JSON AS
$$
DECLARE
v_text varchar;
begin
RAISE NOTICE 'text: %', text;
v_text:=text || '- hello';
return v_text;
end
$$
LANGUAGE 'plpgsql';
By calling like this is working:
SELECT * FROM give_me_text
(
'{"es":"name 1","en":"name 2","de":"name 3","fr":"name 4","pt":"name 5"}'
);
But when I have got a single quote is not working:
SELECT * FROM give_me_text
(
'{"es":"nam'e 1","en":"name 2","de":"name 3","fr":"name 4","pt":"name 5"}'
);
2.- When I am tryhing to insert JSON value with Single quote inside, it is giving me the same error:
This is working:
INSERT INTO public.my_columns VALUES ('{ "name": "Book the First", "author": { "first_name": "Bob", "last_name": "White" } }');
But this is not working:
INSERT INTO public.my_columns VALUES ('{ "name": "Book's the First", "author": { "first_name": "Bob", "last_name": "White" } }');
Any ideas how to escape this single quote? Thanks
In SQL, single quote must be escaped in a string. This is not a valid string:
'{"es":"nam'e 1"}'
because the string ends after "nam. You can escape the single quote by repeating it:
'{"es":"nam''e 1"}'
If you're doing dynamic SQL, you can pass parameters to execute:
execute 'insert into YourTable (col1) values ($1);' using json_var;
Related
I want to create this JSON text with Delphi IDE:
{
"uygulamaninAdi": "ZGVuZW1l",
"uygulamaninSurumu1": "1",
"uygulamaninSurumu2": "0",
"uygulamaninSurumu3": "0",
"uygulamaninSurumu4": "0",
"uygulamaninMimarisi": "1",
"calistirilmaDuzeyi": "1",
"mesajGonderebilmeDurumu": "1",
"konum": "RDpcUHJvZ3JhbWxhbWE="
}
Here are my codes:
procedure TfrmManifestDosyasiOlusturucu.btnOluşturClick(Sender: TObject);
begin
jsGönderilecekMesaj := TJSONObject.Create;
jsGönderilecekMesaj.AddPair('uygulamaninAdi', TNetEncoding.Base64.Encode(edUygulamanınAdı.Text));
jsGönderilecekMesaj.AddPair('uygulamaninSurumu1', edUygulamanınSürümü1.Text);
jsGönderilecekMesaj.AddPair('uygulamaninSurumu2', edUygulamanınSürümü2.Text);
jsGönderilecekMesaj.AddPair('uygulamaninSurumu3', edUygulamanınSürümü3.Text);
jsGönderilecekMesaj.AddPair('uygulamaninSurumu4', edUygulamanınSürümü4.Text);
jsGönderilecekMesaj.AddPair('uygulamaninMimarisi', IntToStr(cbUygulamanınMimarisi.ItemIndex));
jsGönderilecekMesaj.AddPair('calistirilmaDuzeyi', IntToStr(cbÇalıştırılmaDüzeyi.ItemIndex));
jsGönderilecekMesaj.AddPair('mesajGonderebilmeDurumu', IntToStr(cbMesajGönderebilmeDurumu.ItemIndex));
jsGönderilecekMesaj.AddPair('konum', TNetEncoding.Base64.Encode(edManifestDosyasınınOluşturulacağıKonum.Text));
strKomutSatırıParametreleri := '/olustur ' + jsGönderilecekMesaj.ToString;
ShellExecute(0, 'open', 'bin\Manifest Dosyası Oluşturucu (Yardımcı Uygulama).exe', PWideChar(strKomutSatırıParametreleri), nil, SW_HIDE);
end;
But the problem is the Delphi IDE creates this:
{uygulamaninAdi:ZGVuZW1l,uygulamaninSurumu1:1,uygulamaninSurumu2:0,uygulamaninSurumu3:0,uygulamaninSurumu4:0,uygulamaninMimarisi:1,calistirilmaDuzeyi:1,mesajGonderebilmeDurumu:1,konum:RDpcUHJvZ3JhbWxhbWE=}
As far as I know all of keys should be nested with quotes and all of string values should be nested be quotes.
How can I fix my problem?
Try using TJSONObject.ToJSON instead of TNSONObject.ToString.
Also, JSON really isn't well-suited for passing around on the command line. If the target program expects to receive the JSON as a single parameter, and since the JSON has quotes in it and potentially also spaces, you should use AnsiQuotedStr() to add quotes around, and to escape quotes inside, of the JSON string.
I'm starting to fiddle out how to handle JSON in MSSQL 2016+
I simply created a table having a ID (int) and a JSON (nvarchar) column.
Here are my queries to show the issue:
First query just returns the relational table result, nice and as expected.
SELECT * FROM WS_Test
-- Results:
1 { "name": "thomas" }
2 { "name": "peter" }
Second query returns just the json column as "JSON" created my MSSQL.
Not nice, because it outputs the json column content as string and not as parsed JSON.
SELECT json FROM WS_Test FOR JSON PATH
-- Results:
[{"json":"{ \"name\": \"thomas\" }"},{"json":"{ \"name\": \"peter\" }"}]
Third query gives me two result rows with json column content as parsed JSON, good.
SELECT JSON_QUERY(json, '$') as json FROM WS_Test
-- Results:
{ "name": "thomas" }
{ "name": "peter" }
Fourth query gives me the json column contents as ONE (!) JSON object, perfectly parsed.
SELECT JSON_QUERY(json, '$') as json FROM WS_Test FOR JSON PATH
-- Results:
[{"json":{ "name": "thomas" }},{"json":{ "name": "peter" }}]
BUT:
I don't want to have the "json" property containing the json column content in each array object of example four. I just want ONE array containing the column contents, not less, not more. Like this:
[
{
"name": "peter"
},
{
"name": "thomas"
}
]
How can I archive this with just T-SQL? Is this even possible?
The FOR JSON clause will always include the column names - however, you can simply concatenate all the values in your json column into a single result, and then add the square brackets around that.
First, create and populate sample table (Please save us this step in your future questions):
CREATE TABLE WS_Test
(
Id int,
Json nvarchar(1000)
);
INSERT INTO WS_Test(Id, Json) VALUES
(1, '{ "name": "thomas" }'),
(2, '{ "name": "peter" }');
For SQL Server 2017 or higher, use the built in string_agg function:
SELECT '[' + STRING_AGG(Json, ',') + ']' As Result
FROM WS_Test
For lower versions, you can use for xml path with stuff to get the same result as the string_agg:
SELECT STUFF(
(
SELECT ',' + Json
FROM WS_Test
FOR XML PATH('')
), 1, 1, '[')+ ']' As Result
The result for both of these queries will be this:
Result
[{ "name": "thomas" },{ "name": "peter" }]
You can see a live demo on DB<>Fiddle
I am capturing JSON data from a number of services sources to a table in SQL Server; where it is queued for processing. Each of the data sources has a different initial element to identify the type. A fictional example is below.
I can query the content of the file easily enough using json_value (example below) or json_query. What I'm struggling to figure out is identifying which type of file i have in order to commence processing. The identifier is the name of first element "AddressDetails" in the example below. Is there a way in SQL's json querying to get the name of the first element out? Or do I need to push that up to the service that is receiving the data and save the type with the json data?
declare #test table (jsondata nvarchar(max))
insert into #test
select '{
"AddressDetails": {
"type": 1,
"address": {
"Street1": "A Street",
"Street2": "",
"town": "Bristol",
"county": "Avon",
"country": "England"
}
}
} '
select
json_value(jsondata, '$.AddressDetails."type"'),
json_value(jsondata, '$.AddressDetails.address."Street1"'),
json_value(jsondata, '$.AddressDetails.address."Street2"'),
json_value(jsondata, '$.AddressDetails.address."town"'),
json_value(jsondata, '$.AddressDetails.address."county"'),
json_value(jsondata, '$.AddressDetails.address."country"')
from #test
Suppose your structure will remain the same, except the first identifier
you can use the following dynamic part:
UPDATE
SET NOCOUNT ON
IF OBJECT_ID ('tempdb..##Test') IS NOT NULL DROP TABLE ##Test
CREATE TABLE ##TEST (jsondata nvarchar(max))
DECLARE #Cmd NVARCHAR(MAX)=''
insert into ##TEST
select '{
"NameOfIdentifier": {
"type": 1,
"address": {
"Street1": "A Street",
"Street2": "",
"town": "Bristol",
"county": "Avon",
"country": "England"
}
}
}'
SELECT #Cmd+= 'SELECT DISTINCT '''+[Key]+''' as Identifier FROM ##TEST
CROSS APPLY OPENJSON(jsondata ,'''+'$.'+[Key]+''');'
FROM ##TEST
CROSS APPLY OPENJSON (jsondata )
EXEC sp_executesql #Cmd
DROP TABLE ##TEST
you'll get the following result:
Let me know if this helps
I have the following table def:
`CREATE TABLE `TestInfo` (
`Info` json DEFAULT NULL
) ;
`
Am inserting two rows with json values.
INSERT INTO `TestInfo` (`Info`)
VALUES
('{
"statusCode": 200,
"result": {
"summary": {
"area": 0.0009904206008286565
}
}
} '
);
INSERT INTO `TestInfo` (`Info`)
VALUES
(
'{
"statusCode": 200,
"result": {
"summary": {
"area": 0.0009904206008286565,
"realty-society": {
"price-min": {
"property": "price-min",
"min": 110000.00000000001,
"max": 150000000,
"average": 31184468.085106384,
"sum": 1465670000
}
}
}
}
} '
);
When I run the query:
SELECT JSON_EXTRACT(Info, '$.result.summary')
FROM TestInfo ;
it returns the 2 rows. This is fine.
But when I run the same query with double quotes around the path like this:
SELECT JSON_EXTRACT(Info, '$."result.summary"')
FROM TestInfo;
it returns the 2 rows (with the single column) as NULLs.
Ultimately I need to use double quotes for keys that have a hyphen (dash) in them.
I am using MySQL 5.7 on AWS.
Pl help.
Don't put double quotes around the whole path, just around a specific property name that contains special characters, e.g.
SELECT JSON_EXTRACT(Info, '$.result.summary."realty-society"."price-min"')
FROM TestInfo
Yuor code makes . part of the literal property name, rather than a separator between properties. You would use it if you had:
"result.summary": ...
in the object.
This should be works if MYSQL version>=5.7
SELECT Info->>"$.result.summary"
FROM TestInfo ;
I want to load a formatted JSON file, in the form of
{
"EId":"104111",
"Category":"(0)",
"Mac":"ABV",
"Path":"chemin2",
"ID":"System.Byte"
}
by creating first a temporary table with a json column,
create temporary table temp_json (values json);
copy temp_json from '/path_to_the_file/test.json';
select values->>'EId' as EId,
values->>'Category' as Category,
values->>'Mac' as Mac,
values->>'Path' as Path,
values->>'ID' as ID
from(
select json_array_elements(values) as values
from temp_json
) a;
but it shows the following message:
ERROR: invalid input syntax for type JSON
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1: {
COPY temp_json, line 1, column values: "{"
once I erase all the whitespace, the instruction pass with no error.
Assuming a file like this:
{
"EId":"104111",
"Category":"(0)",
"Mac":"ABV",
"Path":"chemin2",
"ID":"System.Byte"
}
{
"EId":"104112",
"Category":"(1)",
"Mac":"CBV",
"Path":"chemin3",
"ID":"System.Byte"
}
The temporary table will receive text not json:
create temporary table temp_json (values text);
\copy temp_json from '/path_to/input.json';
The definitive table will have a json column:
create table t (obj jsonb);
Some string manipulation:
insert into t (obj)
select
regexp_split_to_table(
replace(v, $$"}{"$$, $$"}djue748wBc,l;09{"$$),
'djue748wBc,l;09'
)::jsonb
from (
select string_agg(values, '') as v
from temp_json
) s;
obj
--------------------------------------------------------------------------------------------
{"ID": "System.Byte", "EId": "104111", "Mac": "ABV", "Path": "chemin2", "Category": "(0)"}
{"ID": "System.Byte", "EId": "104112", "Mac": "CBV", "Path": "chemin3", "Category": "(1)"}
I don't think you're properly quoting this. See the docs on quoting, and on copy.
It's certainly possible,
CREATE TEMPORARY TABLE foo
AS
SELECT $${
"EId":"104111",
"Category":"(0)",
"Mac":"ABV",
"Path":"chemin2",
"ID":"System.Byte"
}$$::jsonb AS jsondata;