I have a type named codelist if table of varchar. a variable called "final" of type codelist needs to be converted as json_object.
Like this New = ('1','2','3') needs to be converted to json format like below
{
"New" : ['1','2','3']
}
Please help
try this
declare
tag1 json_object_t;
tag2 json_object_t;
array json_array_t;
begin
tag1:= json_object_t();
tag1.put('Date', sysdate);
tag1.put('Your header', "hellow");
tag2:= json_object_t();
tag2.put('pos1', test(1).1);
tag2.put('pos2', teste(2).2);
array.append(tag2);
end;
If I wasn't very clear, you can follow this link - https://dzone.com/articles/relational-to-json-with-plsql
Related
I am trying to convert Json trying to class object, but the values are not appearing in the new object variable. The resulting object has blank value in string and 0 in integer.
Thanks in advance.
Code:
type
Student =class
public
Name : string;
Age : Integer;
end;
procedure TForm2.Button5Click(Sender: TObject);
var
Student1, Student2: Student;
STR: string;
begin
Student1 := Student.Create;
Student2 := Student.Create;
try
Student1.Name := 'Sam';
Student1.Age := 24;
str := TJson.ObjectToJsonString(Student1);
Form2.outputMemo.Lines.Add(str);
Student2 := TJSON.JsonToObject<Student>(str);
Form2.outputMemo.Lines.Add(Student2.Name);
Form2.outputMemo.Lines.Add(Student2.Age.ToString);
finally
Student1.Free;
Student2.Free;
end;
//Form2.outputMemo.Lines.Text :=TJson.ObjectToJsonObject(Student1);
end;
Output:
{"name":"Sam","age":24}
0
Edit:
I just saw this, and it worked when I changed the names to FName and FAge... what a sorcery!, can anyone please explain the logic behind this?
Delphi Rest.JSON JsonToObject only works with f variables
The internal mapping of JSON fields to Delphi fields is prefixing them with F and changing the following character to upper case. If you want complete control over this you can specify the JSON name with an attribute:
type
Student =class
public
[JSONName('name')]
Name : string;
[JSONName('age')]
Age : Integer;
end;
Note that the JSON names given are case sensitive.
You need to include REST.Json.Types to the uses so that the attribute declaration can be found.
Use case:
Application requires a subset of attributes, based on business rules
Example:
Some students do not require to enter in home address
Database : Oracle
Proposed implementation:
Build json object containing all possible attribute named pairs, then selectively remove specific named pairs
Issue:
Hoped to use native oracle function to remove the specified named pair.
e.g json_object.remove_attribute('home_address');
However Oracle do not appear to provide any such method.
Workaround : Convert json_object to VARCHAR2 string, and then use combination of INSTR and REPLACE to remove named pair.
Illustrative code:
DECLARE
CURSOR cur_student_json (p_s_ref IN VARCHAR2) IS
SELECT JSON_OBJECT(
,'s_surname' value s.s_surname
,'s_forename_1' value s.s_forename_1
,'s_home_address_1' value s.s_home_address_1
RETURNING VARCHAR2 ) student_json
FROM students s
WHERE s.s_ref = p_s_ref;
BEGIN
FOR x IN cur_student_json (p_s_ref) LOOP
vs_student_json:=x.student_json;
EXIT;
END LOOP;
-- Determine student type
vs_student_type:=get_student_type(p_s_ref);
-- Collect list of elements not required, based on student type
FOR x IN cur_json_inorout(vs_student_type) LOOP
-- Remove element from the json
vs_student_json:=json_remove(vs_student_json,x.attribute);
END LOOP;
END;
/
Question:
There must be an elegant method to achieve requirement
Classify under RTFM. Needs Oracle 12.2
DECLARE
-- Declare an object of type JSON_OBJECT_T
l_obj JSON_OBJECT_T;
-- Declare cursor to build json object
CURSOR cur_student_json (p_s_ref IN VARCHAR2) IS
SELECT JSON_OBJECT(
,'s_surname' value s.s_surname
,'s_forename_1' value s.s_forename_1
,'s_home_address_1' value s.s_home_address_1
) student_json
FROM students s
WHERE s.s_ref = p_s_ref;
BEGIN
-- Initialise object
l_obj := JSON_OBJECT_T();
-- Populate the object
FOR x IN cur_student_json (p_s_ref) LOOP
l_obj:=JSON_OBJECT_T.parse(x.student_json);
EXIT;
END LOOP;
-- Determine student type
vs_student_type:=get_student_type(p_s_ref);
-- Collect list of elements not required, based on student type
FOR x IN cur_json_inorout(vs_student_type) LOOP
-- Remove element from the json
l_obj.remove(x.attribute);
END LOOP;
-- Display modified object
dbms_output.put_line(l_obj.stringify);
END;
/
I have a simple PostgreSQL function I want to pass complex JSON to:
CREATE OR REPLACE FUNCTION foo(sync_data json)
RETURNS json AS
$body$
DECLARE
...
END;
$body$ LANGUAGE plpgsql;
Calling it with something like this:
SELECT foo('{"deviceId": 1, "shops": [{"id": 1}, {"id": 2}]}'::json);
gives me the following error:
ERROR: malformed array literal: "{"id": 1}"
DETAIL: Unexpected array element.
CONTEXT: PL/pgSQL function foo(json) line 8 at SQL statement
SQL state: 22P02
I need to pass complex JSON as a parameter, containing arrays of objects.
Thanks!
PS: Here is the full function text:
CREATE OR REPLACE FUNCTION foo(sync_data json)
RETURNS json AS
$body$
DECLARE
res_json json;
device_id integer;
shops json ARRAY;
BEGIN
SELECT json_extract_path(sync_data, 'deviceId') INTO device_id;
SELECT json_array_elements(json_extract_path(sync_data, 'shops')) INTO shops;
SELECT json_build_object('devId', device_id) INTO res_json;
RETURN res_json;
END;
$body$ LANGUAGE plpgsql;
The problem was with the syntax inside the function.
The correct syntax for parsing array of objects and assigning it to json ARRAY:
CREATE OR REPLACE FUNCTION foo(sync_data json)
RETURNS json AS
$body$
DECLARE
res_json json;
device_id integer;
shops json ARRAY;
BEGIN
SELECT json_extract_path(sync_data, 'deviceId') INTO device_id;
shops := ARRAY(SELECT json_array_elements(sync_data->'shops'));
SELECT json_build_object('Dev_id', device_id, 'shop1', shops[1], 'shop2', shops[2]) INTO res_json;
RETURN res_json;
END;
$body$ LANGUAGE plpgsql;
Thanks to eurotrash and Abelisto!
I have a text column that contains JSON and also plan text. I want to convert it to JSON, and then select a particular property. For example:
user_data
_________
{"user": {"name": "jim"}}
{"user": {"name": "sally"}}
some random data string
I've tried:
select user_data::json#>'{user,name}' from users
I get:
ERROR: invalid input syntax for type json
DETAIL: Token "some" is invalid.
CONTEXT: JSON user_data, line 1: some...
Is it possible to prevent this?
If you want to skip the rows with invalid JSON, you must first test if the text is valid JSON. You can do this by creating a function which will attempt to parse the value, and catch the exception for invalid JSON values.
CREATE OR REPLACE FUNCTION is_json(input_text varchar) RETURNS boolean AS $$
DECLARE
maybe_json json;
BEGIN
BEGIN
maybe_json := input_text;
EXCEPTION WHEN others THEN
RETURN FALSE;
END;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
When you have that, you could use the is_json function in a CASE or WHERE clause to narrow down the valid values.
-- this can eliminate invalid values
SELECT user_data::json #> '{user,name}'
FROM users WHERE is_json(user_data);
-- or this if you want to fill will NULLs
SELECT
CASE
WHEN is_json(user_data)
THEN user_data::json #> '{user,name}'
ELSE
NULL
END
FROM users;
Use this function:
create or replace function is_json(text)
returns boolean language plpgsql immutable as $$
begin
perform $1::json;
return true;
exception
when invalid_text_representation then
return false;
end $$;
Test:
with users(user_data) as (
values
('{"user": {"name": "jim"}}'),
('not json'),
('{"user": {"name": "sally"}}'),
('also not json')
)
select user_data::json#>'{user,name}' as name
from users
where is_json(user_data);
name
---------
"jim"
"sally"
(2 rows)
Others have already suggested ways to check if the JSON is valid, but I feel that rather than check that, why not already cast it?
I use this function (JSONB, but you can easily change it to JSON):
CREATE OR REPLACE FUNCTION safe_cast_to_jsonb(input TEXT) RETURNS JSONB AS
$$
DECLARE
output JSONB DEFAULT NULL;
BEGIN
BEGIN
output := input::JSONB;
EXCEPTION
WHEN OTHERS THEN RAISE NOTICE 'INVALID JSONB';
RETURN NULL;
END;
RETURN output;
END;
$$ LANGUAGE plpgsql;
i'm trying once again to work with postgres 9.4 and the new json functionalities and might have encountered a bug. The Problem is that once i have generated a json-string via to_json(..) i cant transform it back to an Composite type because postgres cant handle the json-array inside.
When i write it in postgres Notation it works and i can even access all the fields inside the Array.
Does anyone knows a better workarround?
Example 1: composite type to json and back
DROP TYPE IF EXISTS myType;
CREATE TYPE myType AS (
since TIMESTAMP,
words TEXT[]
);
DO $$
DECLARE
_my_variable myType;
_my_json JSON;
BEGIN
_my_variable := ROW(now(),ARRAY['Here','is','a','List','of','Words']);
_my_json := to_json(_my_variable);
RAISE INFO 'how my json looks like: %', _my_json;
--{"since":"2015-06-30T09:12:35.12346","word":["Here","is","a","List","of","Words"]}
_my_variable := json_populate_record(NULL::myType,_my_json);
--ERROR: malformed array literal: "["Here","is","a","List","of","Words"]"
--DETAIL: "[" must introduce explicitly-specified array dimensions.
--CONTEXT: PL/pgSQL function inline_code_block line 13 at assignment
END $$;
Example 2: json with postgres-notation like array to composite type
DO $$
DECLARE
_my_variable myType;
_my_json JSON;
BEGIN
_my_json := '{"since":"2015-06-30T09:12:35.12346","words": "{Here,is,a,List,of,Words}" }';
_my_variable := json_populate_record(NULL::myType,_my_json);
RAISE INFO 'how my object looks like: %', _my_variable;
RAISE INFO 'how my array looks like: %', _my_variable.words;
--("2015-06-30 09:12:35.12346","{Here,is,a,List,of,Words}")
END $$;