How to get specific json object from json array using json_query in oracle - sql

For example, I have a json array like below
[
{ id: 1, name: "larry" },
{ id: 2, name: "curly" },
{ id: 3, name: "moe" }
]
How can I get the json object which name is curly using json_query function?

The answer depends on your Oracle version, which you did not include. (Always include your database version, especially in questions about JSON!)
In Oracle 19 (I think - perhaps also in Oracle 18) you can use JSON_QUERY with a path expression with a predicate, something like this:
with
sample_data (j_arr) as (
select '
[
{ id: 1, name: "larry" },
{ id: 2, name: "curly" },
{ id: 3, name: "moe" }
]
' from dual
)
select json_query(j_arr, '$[*]?(#.name == "curly")' returning varchar2) as curly
from sample_data
;
CURLY
-----------------
{
"id" : 2,
"name" : "curly"
}

Related

useGetList fetched data sorted by id ignoring sort option

The problem is that data fetched by useGetList is sorted by ids of the objects and ignores the order by other keys given by my backend. This is my call example (try to order by name):
const { data, loading } = useGetList(
'my-controller-path',
{ page: 1, perPage: 10000 },
{ field: 'name', order: 'ASC' },
{}
)
console.log(data)
When I print data after this call, data is sorted by 'id' and not by 'name'. It's not a problem with the backend because I hardcoded returning data to eliminate this from equation. Data provided from backend:
data: [
{ id: 2, name: 'Ana'},
{ id: 3, name: 'Bea'},
{ id: 1, name: 'Cena'}
]
And when I print data on console after using useGetList:
[
{id: 1, name: "Cena"},
{id: 2, name: "Ana"},
{id: 3, name: "Bea"}
]
Any idea what is causing the problem? I read the source code of useGetList and don't quite understand if the problem lays there. The link to source code.
How does your API works ? In my case, I needed to map the sort properties like so:
getList: async (
resource,
{ pagination: { page, perPage }, sort: { field, order }, filter }
) => {
const query = {
...filter,
sort: order.toLowerCase(),
order: field,
page: JSON.stringify(page),
limit: JSON.stringify(perPage),
};
...
}
in my custom data provider to match my API sort and order properties.

Deep assertion on JSON array with contains in Karate

Scenario:
Given def cat =
"""
{
name: 'Billie',
kittens: [
{ id: 23, name: 'Bob', age: 35 },
{ id: 42, name: 'Wild', age: 25 }
]
}
"""
Then match cat.kittens contains [{ id: 42, name: 'Wild' }, { id: 23, name: 'Bob' }]
As seen in the example, I am not worried about 'age'. I understand that I can use '#ignore'. Is there any other way, if I have lot of such nodes that I have to ignore.
I am just thinking, can it work with JSON arrays as it does with JSON Objects. asserting only specified nodes.
error:
assert.feature:24 - path: $.kittens[*], actual: [{"id":23,"name":"Bob","age":35},{"id":42,"name":"Wild","age":25}], expected: {id=42, name=Wild}, reason: actual value does not contain expected
EDIT:
I tried something suggested in Karate - how to check if array contains values?
but that did not help me. I am not looking for schema-validation instead I am looking for functional validation where every object may have different values for keys.
Below one fails
Scenario:
Given def cat =
"""
{
name: 'Billie',
kittens: [
{ id: 23, name: 'Bob', age: 35 },
{ id: 42, name: 'Wild', age: 25 }
]
}
"""
* def expected = [{ id: 42, name: 'Wild' }, { id: 23, name: 'Bob' }]
Then match cat.kittens contains '#(^expected)'
This one works fine but this is not helping me.
Scenario:
Given def cat =
"""
{
name: 'Billie',
kittens: [
{ id: 23, name: 'Bob', age: 35 },
{ id: 42, name: 'Wild', age: 25 }
]
}
"""
* def expected = { id: 42, name: 'Wild' }
Then match cat.kittens contains '#(^expected)'
Currently, I am reading arrays separately and asserting them with loop.
Just adding the word deep works in 0.9.6.RC4
Then match cat.kittens contains deep [{ id: 42, name: 'Wild' }, { id: 23, name: 'Bob' }]
I don't understand why the linked answer when I closed your first question did not help you. Maybe I don't understand, and someone else can provide a better answer.

How do I perform a SQL update on a list inside one of my table rows?

I have a table with parameters as shown below.
{
id: 1,
title: 'waccos',
description: 'Making an operating system in wacc',
est_duration: 420,
exp_req: 'any',
langs: [ 1 ],
owner: 1,
members: [ 1, 2 ]
},
I want to use SQL to add a new member into the member list, but I do not know how to. The table is called testprojects. I've tried using
(update testprojects
set members = members || $1
where title is $2;', [name, title])
but I think that is wrong. Could anyone help me please?
This is the table of members so far.
[
{ id: 1, name: 'A' },
{ id: 2, name: 'K' },
{ id: 3, name: 'S' },
{ id: 5, name: 'd' },
{ id: 6, name: 'J' },
{ id: 7, name: 'E' },
{ id: 8, name: 'a' }
]

How to delete a jsonb item in a nested psql array

I have a table users:
`CREATE TABLE users(
id SERIAL PRIMARY KEY NOT NULL,
username TEXT UNIQUE,
saved_articles JSONB[],
)`
I added a user like so:
"INSERT INTO users (username, saved_articles) VALUES (?, array[]::jsonb[]) RETURNING id, username, saved_articles"
After adding some articles I have this data shape:
{ id: 1,
username: 'test',
saved_articles:
[ { url: 'test',
title: '',
author: '',
source: '',
content:"",
urlToImage: ''
},
{ url: 'not-test',
title: '',
author: '',
source: '',
content:"",
urlToImage: ''
}
]
}
I want to be able to delete a specific item from the saved_articles array based on the url value.
For example, if my url value is 'test', after running the query my data should look like:
{ id: 1,
username: 'test',
saved_articles:
[ { url: 'not-test',
title: '',
author: '',
source: '',
content:"",
urlToImage: ''
}
]
}
First of all, the format of JSONB columns's value should be fixed. That might be tested through CASTing AS JSONB by a SELECT statement such as
SELECT '{ "id": "1",
"username": "test",
"saved_articles":
[ { "url": "test",
"title": "",
"author": "",
"source": "",
"content":"",
"urlToImage": ""
},
{ "url": "not-test",
"title": "",
"author": "",
"source": "",
"content":"",
"urlToImage": ""
}
]}'::jsonb
whether returns error or not.
Then, remove the desired element from the array by use of jsonb_array_elements(json_data -> 'saved_articles') function together with ->> 'url' != 'test' criteria.
And then reconstruct the array by remaining elements by using jsonb_build_array and jsonb_object_agg.
At the last step concatenate the part which doesn't contain that individual array extracted by json_data #- '{saved_articles}' :
SELECT js0||jsonb_object_agg( 'saved_articles', js1 ) AS "Result JSONB"
FROM
(
SELECT json_data #- '{saved_articles}' AS js0, jsonb_build_array( js ) AS js1
FROM tab
CROSS JOIN jsonb_array_elements(json_data -> 'saved_articles') js
WHERE js ->> 'url' != 'test'
) q
GROUP BY js0
Demo

Take json value in sql without JSON_VALUE

i want to take value (In SQL Server) in json object without JSON_VALUE
The json value :
{{
"Url": "****",
"Token": "",
"Data": {
"role_id": 1001,
"data": {
"stringvalue": [
{
"minage": "21"
},
{
"maxage": "55"
},
{
"primary_identity_file": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QCcUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAIAcAmcAFHpFZEQyY1ZzbGVyRzNrcF8yTjhHHAIoAGJGQk1EMDEwMDBhYzAwMzAwMDAwMjMxMDAwMDQxNzQwMDAwYjQ3YjAwMDBhMTgyMDAwMDliY2EwMDAwMjkyMDAxMDBmODJhMDEwMGFiMzQwMTAwMDgzZTAxMDBjZGM0MDEwMP/iAhxJQ0NfUFJPRklMRQABAQAAAgxsY21zAhAAAG1udHJSR0IgWFlaIA"
}
]
}
}
}}
what i trying to do is to take "primary_identity_file" value
the result should be :
data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QCcUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAIAcAmcAFHpFZEQyY1ZzbGVyRzNrcF8yTjhHHAIoAGJGQk1EMDEwMDBhYzAwMzAwMDAwMjMxMDAwMDQxNzQwMDAwYjQ3YjAwMDBhMTgyMDAwMDliY2EwMDAwMjkyMDAxMDBmODJhMDEwMGFiMzQwMTAwMDgzZTAxMDBjZGM0MDEwMP/iAhxJQ0NfUFJPRklMRQABAQAAAgxsY21zAhAAAG1udHJSR0IgWFlaIA
** NOTE primary_identity_file value is more than 10K character
I'd try something like that:
select substring(vlv3, 1, charindex('"', vlv3)-1) as vlv4
from (
select substring(vlv2, charindex('"', vlv2)+1, len(vlv2)) as vlv3
from (
select substring(vlv, charindex('"primary_identity_file"', vlv)+23, len(vlv)) as vlv2
from test
) as test2
) as test3
You can rewrite in more readable way as stored procedure
Sample fiddle http://sqlfiddle.com/#!18/a122b/7