How to get id from text - mysql

I have value text:
{
"4384": {
"idRoomSv": 4384,
"NumRoom": 2,
"RoomId": 269
}
}
I want to get RoomId. It is return :269.
Can you help me? Thank very much!

If you have a recent version of MariaDB or MySQL, you can use the JSON_EXTRACT function.
Edit: try on your sql client the code below
SET #json = '{
"4384": {
"idRoomSv": 4384,
"NumRoom": 2,
"RoomId": 269
}
}';
SELECT JSON_EXTRACT(#json, '$.*.RoomId');
And the result is :
JSON_EXTRACT(#json, '$.*.RoomId')
1 [269]
The JSON_EXTRACT function accepts a JSON document for the firtst parameter. The second parameter is a JSONPath expression :
$ : is the root element
* : wildcard = all elements regardless their names
RoomId : value of that field

Related

The argument 2 of the "JSON_VALUE or JSON_QUERY" must be a string literal

I am passing this JSON to a stored procedure in SQL Server
{
"individual": [
{
"app_id": 1057029,
"size": 2
},
{
"app_id": 1057053,
"size": 3
},
{
"app_id": 1057048,
"size": 1
}
]
}
In the stored procedure I am extracting values of app_id and size as under
SET #len = JSON_VALUE(#json, CONCAT('$.individual[', #i, '].size'));
SET #appId = JSON_VALUE(#json, CONCAT('$.individual[', #i, '].app_id'));
(Here i is index variable incrementing in a loop)
This works perfect on Microsoft SQL Server 2017 (version 14.0.1000.169)
But on Microsoft SQL Server 2016 (version 13.0.4604.0) I am getting error:
JSON_Value error: The argument 2 of the "JSON_VALUE or JSON_QUERY"
must be a string literal
Please note this is not duplicate as I already have referred questions below on SO but still didn't get solution.
JSON_Value error: The argument 2 of the "JSON_VALUE or JSON_QUERY" must be a string literal
SQL Sever 2016 - Inconsistent Behavior - The argument 2 of the "JSON_VALUE or JSON_QUERY" must be a string literal
Update
Why this is not duplicate question?
None of the other questions discusses the issue in clear precise way. They have mentioned specifics instead. Rather in this question, I have mentioned use of variable #i which is precisely causing this error. JSON_VALUE works in MSSQL2016 but it doesn't support variables as second param, that precisely is the problem here. As a workaround, we've to use OPENJSON but again writing OPENJSON query to get record of particular index from json is tricky. None of the answers to other similar questions discusses this clearly. I am going to write an answer in some time demonstrating it all.
This example demonstrates the use of OpenJson for your JSON and desired query. I've never used OpenJson but found the Microsoft documentation more than adequate. In the last SELECT in this example, the app_id and size are columns in a table with each value pair as a row. Now you don't have to loop through an array; you now have a standard table to work with.
DECLARE #json nvarchar(max) = '{
"individual": [
{
"app_id": 1057029,
"size": 2
},
{
"app_id": 1057053,
"size": 3
},
{
"app_id": 1057048,
"size": 1
}
]
}';
SELECT * FROM OpenJson(#json);
SELECT * FROM OpenJson(#json, '$.individual');
SELECT * FROM OPENJSON(#json, '$.individual')
WITH (
app_id int,
size int
) as apps
;
The output:

Oracle json_transform replace particular value on any level

I need to replace some values in Oracle 19 column that is CLOB with JSON constraint, but cannot find a right way to do it. Json can be big and I suppose regex function on string may not work due to the length restrictions.
My json may have 'locationId' property at any level with some values. Let's say I have bad value 000 and want to replace it with 111, so everywhere where is "locationId":"000" it becomes "locationId":"111".
I'm trying to use next json_transform command:
SELECT json_transform('
{
"a": {
"locationId":"000"
},
"b": {
"locationId":"111",
"x": {
"locationId":"000"
}
}
}', REPLACE '$..locationId?(# == "000")' = '111' IGNORE ON MISSING)
FROM dual
But it returns unchanged json, when next query for the same json fetches values to replace properly :
SELECT json_query('
{
"a": {
"locationId":"000"
},
"b": {
"locationId":"111",
"x": {
"locationId":"000"
}
}
}', '$..locationId?(# == "000")' WITH WRAPPER)
FROM dual
Result:
["000","000"]
There is no any documentation or examples how to use filters within json_transform, so I'm not sure it's even possible.
Maybe anybody know how to do it? Doesn't matter with json functions or not.
Links I use:
Oracle Json Path Expressions
Oracle json_query
Oracle json_transform
Have you seen that even
REPLACE '$..locationId' = '111' IGNORE ON MISSING
doesn't change anything ?
(at least in Cloud 21c)
It's more complicated:
SELECT json_transform('
{
"locationId" : "000",
"a": {
"locationId":"000"
},
"b": {
"locationId":"000",
"x": {
"locationId":"000",
"y": {
"locationId":"000"
}
}
}
}'
, REPLACE '$.locationId?(# == "000")' = '111' IGNORE ON MISSING
, REPLACE '$.*.locationId?(# == "000")' = '111' IGNORE ON MISSING
, REPLACE '$.*.*.locationId?(# == "000")' = '111' IGNORE ON MISSING
, REPLACE '$.*.*.*.locationId?(# == "000")' = '111' IGNORE ON MISSING
)
FROM dual;
Gives:
{"locationId":"111","a":{"locationId":"111"},"b":{"locationId":"111","x":{"locationId":"111","y":{"locationId":"111"}}}}

How can I use the oracle REGEXP_SUBSTR to extract specific json values?

I have some columns in my Oracle database that contains json and to extract it's data in a query, I use REGEXP_SUBSTR.
In the following example, value is a column in the table DOSSIER that contains json. The regex extract the value of the property client.reference in that json
SELECT REGEXP_SUBSTR(value, '"client"(.*?)"reference":"([^"]+)"', 1, 1, NULL, 2) FROM DOSSIER;
So if the json looks like this :
[...],
"client": {
"someproperty":"123",
"someobject": {
[...]
},
"reference":"ABCD",
"someotherproperty":"456"
},
[...]
The SQL query will return ABDC.
My problem is that some json have multiple instance of "client", for example :
[...],
"contract": {
"client":"Name of the client",
"supplier": {
"reference":"EFGH"
}
},
[...],
"client": {
"someproperty":"123",
"someobject": {
[...]
},
"reference":"ABCD",
"someotherproperty":"456"
},
[...]
You get the issue, now the SQL query will return EFGH, which is the supplier's reference.
How can I make sure that "reference" is contained in a json object "client" ?
EDIT : I'm on Oracle 11g so I can't use the JSON API and I would like to avoid using third-party package
Assuming you are using Oracle 12c or later then you should NOT use regular expressions and should use Oracle's JSON functions.
If you have the table and data:
CREATE TABLE table_name ( value CLOB CHECK ( value IS JSON ) );
INSERT INTO table_name (
value
) VALUES (
'{
"contract": {
"client":"Name of the client",
"supplier": {
"reference":"EFGH"
}
},
"client": {
"someproperty":"123",
"someobject": {},
"reference":"ABCD",
"someotherproperty":"456"
}
}'
);
Then you can use the query:
SELECT JSON_VALUE( value, '$.client.reference' ) AS reference
FROM table_name;
Which outputs:
REFERENCE
ABCD
db<>fiddle here
If you are using Oracle 11 or earlier then you could use the third-party PLJSON package to parse JSON in PL/SQL. For example, this question.
Or enable Java within the database and then use CREATE JAVA (or the loadjava utility) to add a Java class that can parse JSON to the database and then wrap it in an Oracle function and use that.
I faced similar issue recently. If "reference" is a property that is only present inside "client" object, this will solve:
SELECT reference FROM (
SELECT DISTINCT
REGEXP_SUBSTR(
DBMS_LOB.SUBSTR(
value,
4000
),
'"reference":"(.+?)"',
1, 1, 'c', 1) reference
FROM DOSSIER
) WHERE reference IS NOT null;
You can also try to adapt the regex to your need.
Edit:
In my case, column type is CLOB and that's why I use DBMS_LOB.SUBSTR function there. You can remove this function and pass column directly in REGEXP_SUBSTR.

How to insert json text into one of the column in a table in sql server

I have json code in which I am trying to get output. So, in one of the column in my code like "RETURN_MESSAGE" value is json ...so,I am trying to get the value in return_message column when I run select query but it is giving me null. So ,how can I get the json text which is inside "RETURN_MESSAGE" .Can anyone help me on this please
declare #json varchar(max) ='[
{
"SP_NAME":"test"
,"KEY":"a39a"
,"EXEC_ID":4857
,"RETURN_MESSAGE":{
"d":{
"Key":"e77d83af-2827-447c-8b98-46c9e9d0a39a"
,"reqCountLimit":0
,"reqFormat":"JSON"
,"reqExecutionMode":"B"
,"srcExtid":284
,"tgtExtId":4857
,"srcTableName":"KDP_STG_SAP_CSKS"
,"SourceSchema":"QCDC1"
,"serviceId":"1001"
,"reqBatchRecCount":15000
,"compressedFlag":"Y"
,"mDataFlag":"Y"
,"reqDeltaFromUTC":"0000-00-00T00: 00: 00"
,"reqExtMode":"F"
,"reqStatusType":"S"
,"reqStatus":"Successfully Batch Job Started !!!"
,"OBJECT_MDATA":{
"results":[
{
"Fieldname":"KDP_TABKEY"
,"Datatype":"CHAR"
,"Length":78
}
,{
"Fieldname":"KDP_CHNGIND"
,"Datatype":"CHAR"
,"Length":1
}
]
}
,"DELTA_CONFIG":[
]
}
}
}]'
SELECT * FROM OPENJSON(#json) with(SP_NAME varchar(50),KEY varchar(255),EXEC_ID int,RETURN_MESSAGE varchar(max))
output
sp_name key exec_id RETURN_MESSAGE
test a39a 4857 NULL
You can try the follwoing query.
SELECT * FROM OPENJSON(#json)
WITH(SP_NAME VARCHAR(50),KEY VARCHAR(255),EXEC_ID INT,RETURN_MESSAGE NVARCHAR(MAX) AS JSON)

MongoDB equivalent to NOW() + INTERVAL

I'm currently working on converting our PHP backend from MySQL to MongoDB.
We are often using something like this in MySQL:
UPDATE table_1 SET completion_time = NOW() + INTERVAL 90 MINUTE WHERE id = 1;
How would I do this in MongoDB? Do I need to use 2 queries? First query to set completion_time with $currentDate and the 2nd query to increment it? I've read that $inc doesn't work on Dates in MongoDB, tho ...
You could try creating a date variable that holds the current date + 90 minutes later which you can then use to set the completion_time field with in your update:
var ninetyMinutesLater = new Date();
ninetyMinutesLater.setMinutes(ninetyMinutesLater.getMinutes() + 90);
db.table_1.update(
{ "_id": 1 },
{
"$set": {
"completion_time": ninetyMinutesLater
}
}
);
I see you have have tagged this with mongodb-php so I assume you are using PHP. MongoDB does have a $currentDate operator but currently there is no way to actually set an offset to that date.
For example I tried #diwakar's answer on 3.0:
> db.table_1.update({"id":1 },{completion_time: { $add: [ "$currentDate", 90 ] }})
2015-03-23T11:22:05.497+0000 E QUERY Error: field names cannot start with $ [$add]
at Error (<anonymous>)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:160:19)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:164:18)
at DBCollection._validateUpdateDoc (src/mongo/shell/collection.js:387:14)
at Object.findOperations.updateOne (src/mongo/shell/bulk_api.js:675:20)
at DBCollection.update (src/mongo/shell/collection.js:454:22)
at (shell):1:12 at src/mongo/shell/collection.js:160
So currently this needs to be done client side like so:
$mongo->collection->insert(['completion_time' => new MongoDate(time() + (60*90))])
It seems that is the only way.
Starting with MongoDB v5.0+, you can use $dateAdd with $$NOW.
db.collection.update({
_id: 1
},
[
{
$set: {
completion_time: {
"$dateAdd": {
"startDate": "$$NOW",
"unit": "minute",
"amount": 90
}
}
}
}
])
Here is the Mongo Playground for your reference.
use
db.collection.UpdateOne({ _id:id},{
$set:{
"completion_time": $add:[ $currentDate , (60*90)]
}
})
Please try this definitely work,
db.table_1.update({"id":1 },{completion_time: { $add: [ "$date", 90 ] }})