insert jsonb data in postgresql, option array or objects, valid way - sql

I have this update, i've read postgresql documentation, but nothing clear about how to insert data, some tutorials options:
1.with '{}'
2.with {}
3.with '[]' <-- array of objects
and most dont' use '::jsonb' like is indicated on:
https://www.postgresql.org/docs/9.4/static/datatype-json.html
here my code:
UPDATE customer set phones ='{ {"type": "mobile", "phone": "001001"} ,
{"type": "fix", "phone": "002002"} }'::jsonb
where id ='4ca27243-6a55-4855-b0e6-d6e1d957f289';
I get this error:
ERROR: invalid input syntax for type json
LINE 1: UPDATE customer set phones ='{ {"type": "mobile", "phone": ...
^
DETAIL: Expected string or "}", but found "{".
CONTEXT: JSON data, line 1: { {...
SQL state: 22P02
Character: 29
I need just record a lit of phones, need to enclose in a big name object like? I mean for javascript , array of objets is not an object, but i dont know if that is accepted in jsonb of postresql
{ phones:[ {"type": "mobile", "phone": "001001"} ,
{"type": "fix", "phone": "002002"} ] }

Example 1 (object):
CREATE TABLE customer {
contact JSONB
}
update customer
set contact = '{ "phones":[ {"type": "mobile", "phone": "001001"} , {"type": "fix", "phone": "002002"} ] }'
where id = '4ca27243-6a55-4855-b0e6-d6e1d957f289';
Example 2 (array):
CREATE TABLE customer {
phones JSONB
}
update customer
set phones = '[ {"type": "mobile", "phone": "001001"} , {"type": "fix", "phone": "002002"} ]'
where id = '4ca27243-6a55-4855-b0e6-d6e1d957f289';
Notes:
My PostgreSQL version
select version();
PostgreSQL 11.2 (Debian 11.2-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
Be sure to enclose the keys and values with double quotes.

'{}' is array type in postgres. if you use jsonb, use regular '[]' for array:
so=# select jsonb_pretty('{"phones":[ {"type": "mobile", "phone": "001001"} , {"type": "fix", "phone": "002002"} ] }');
jsonb_pretty
{
"phones": [
{
"type": "mobile",
"phone": "001001"
},
{
"type": "fix",
"phone": "002002"
}
]
}
(1 row)
Time: 0.486 ms
or:
so=# select jsonb_pretty('[ {"type": "mobile", "phone": "001001"} , {"type": "fix", "phone": "002002"} ]');
jsonb_pretty
[
{
"type": "mobile",
"phone": "001001"
},
{
"type": "fix",
"phone": "002002"
}
]
(1 row)

Related

Select data from Json array MS SQL Server

I have to select data from Json like this:
[
{
"id": 10100,
"externalId": "100000035",
"name": "Test1",
"companyId": 10099,
"phone": "0738003811",
"email": "test#Test.com",
"mainAddress": {
"county": "UK",
"province": "test",
"zipCode": "01234",
"city": "test",
"street": "test",
"gln": "44,37489331;26,21941193",
"country": {
"iso2": "UK",
"iso3": "UK"
}
},
"active": false,
"main": true,
"stores": [
"Test"
],
"attributes": [
{
"attributeId": 1059,
"attributeName": "CH6 name",
"attributeExternalId": null,
"attributeValueId": 74292,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Unknown"
},
{
"attributeId": 1061,
"attributeName": "BD",
"attributeExternalId": null,
"attributeValueId": 81720,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Not assigned"
}
],
"daysSinceLastOrder": null
},
{
"id": 62606,
"externalId": "VL_LC_000190",
"name": "Test",
"companyId": 17793,
"phone": "44333424",
"email": "test#email.com",
"mainAddress": {
"firmName": "test",
"county": "test",
"province": "test",
"zipCode": "247555",
"city": "test",
"street": "test",
"gln": "44.8773851;23.9223518",
"country": {
"iso2": "RO",
"iso3": "ROU"
},
"phone": "07547063789"
},
"active": true,
"main": false,
"stores": [
"Valcea"
],
"attributes": [
{
"attributeId": 1042,
"attributeName": "Type of location",
"attributeExternalId": "TYPE_OF_DIVISION",
"attributeValueId": 34506,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": "Small OTC (<40mp)",
"attributePlainValue": "Small OTC (<40mp)"
},
{
"attributeId": 17,
"attributeName": "Limit for payment",
"attributeExternalId": "LIMIT_FOR_PAYMENT_IN_DAYS",
"attributeValueId": 59120,
"attributeValueType": "NUMBER",
"attributeValueEid": null,
"attributePlainValue": "28"
}
],
"daysSinceLastOrder": 147
}
]
I know how to select data from simple json object using "FROM OPENJSON",
but now I have to select a
AttributeValueId, AttributeId and AttributeName, attributePlainValue and CompanyId for each Attribute. So I dont know how to select data from attributes array and then how to join to this CompanyId which is one level up.
Maybe someone knows how write this query.
As mentioned by #lptr in the comments:
You need to pass the result of one OPENJSON to another, using CROSS APPLY. You can select a whole JSON object or array as a property, by using the syntax AS JSON
select
t1.companyid,
t2.*
from openjson(#j)
with (
companyId int,
attributes nvarchar(max) as json
) as t1
cross apply openjson(t1.attributes)
with
(
attributeId int,
attributeName nvarchar(100),
attributeValueId nvarchar(100),
attributePlainValue nvarchar(100)
) as t2;
db<>fiddle
For example, you can use code like this.
f1.metaData->"$.identity.customerID" = '.$customerID.'

How to get data from json column in mssql

I'm struggling to write a query that gets value from json column with some specific conditions. I have a table named Table1 with a column of type nvarchar(max) named Data that contains some json values. The json itself looks like this:
{
"Addresses": [
{
"ApartmentNumber": "1",
"City": "Rome",
"CountryCode": "IT",
"HouseNumber": "2",
"Post": "Rome",
"PostalCode": "11-111",
"Region": "Rome",
"Street": "Italian",
"StreetPrefix": "St.",
"TypeCode": "PERMANENT"
},
{
"ApartmentNumber": "11",
"City": "Madrid",
"CountryCode": "ES",
"HouseNumber": "22",
"Post": "Madrid",
"PostalCode": "11-111",
"Region": "Madrid",
"Street": "Spanish",
"StreetPrefix": "St.",
"TypeCode": "CORRESPONDENCE"
}
],
"Contacts": [
{
"TypeCode": "EMAIL",
"DefaultContact": false,
"Value": "sample#xyz.com"
}
],
"PersonData": {
"BirthDate": "1968-08-03T00:00:00",
"CitizenshipCode": "US",
"DeathDate": "0001-01-01T00:00:00",
"FirstName": "John",
"Gender": "M",
"LastName": "Jones"
}
}
I would like to get a value of CountryCode from the Addresses node where TypeCode is "CORRESPONDENCE". I tried to achieve that with combinations of JSON_VALUE and JSON_QUERY functions but I failed. Below are some examples of my trials:
query:
SELECT JSON_QUERY(t.Data, '$.Addresses') AS Address FROM [Table1] t
result:
[
{
"ApartmentNumber": "1",
"City": "Rome",
"CountryCode": "IT",
"HouseNumber": "2",
"Post": "Rome",
"PostalCode": "11-111",
"Region": "Rome",
"Street": "Italian",
"StreetPrefix": "St.",
"TypeCode": "PERMANENT"
},
{
"ApartmentNumber": "11",
"City": "Madrid",
"CountryCode": "ES",
"HouseNumber": "22",
"Post": "Madrid",
"PostalCode": "11-111",
"Region": "Madrid",
"Street": "Spanish",
"StreetPrefix": "St.",
"TypeCode": "CORRESPONDENCE"
}
]
or this:
query:
select top 1 JSON_VALUE(t.Data, '$.PersonData.LastName') FROM [Table1] t where ISJSON(t.Data) > 0 and JSON_VALUE(pd.BusinessPartner, '$.PersonData.Gender') = 'F'
result:
"Jones"
but when i to write similar query with Addresses as condition:
query:
select top 1 JSON_VALUE(t.Data, '$.Addresses.CountryCode') FROM [Table1] t where ISJSON(t.Data) > 0 and JSON_VALUE(t.Data,'$.Addresses.TypeCode') = 'CORRESPONDENCE'
I get empty string as the result.
Thanks in advance
From SQL Server 2016, you can query on JSON column. See the documentation : Work with JSON data
The interesting part for you it's Analyze JSON data with SQL queries.
This done :
select Id, PostalCode
from Address
CROSS APPLY OPENJSON (Address.Data, N'$.Addresses')
WITH (
TypeCode varchar(50) '$.TypeCode',
PostalCode varchar(50) '$.PostalCode'
) AS AddressesJsonData
WHERE TypeCode = N'PERMANENT'

Correct way to create "record" field in Avro schema

I am trying to understand Avro schemas and stuck with complex types (record). The problem is very simple: create a schema which contains one record filed with two primitive fields (string and timestamp) nested to record. I see two options for the schema:
option 1
{
"type": "record",
"name": "cool_subject",
"namespace": "com.example",
"fields": [
{
"name": "field_1",
"type": "record"
"fields": [
{"name": "operation", "type": "string"},
{"name": "timestamp", "type": "long", "logical_type": "timestamp_millis"}
]
}
]
}
option 2
{
"type": "record",
"name": "cool_subject",
"namespace": "com.example",
"fields": [
{
"name": "field_1",
"type": {
"type": "record",
"name": "field_1_type",
"fields": [
{"name": "operation", "type": "string"},
{"name": "timestamp", "type": {"type": "long", "logical_type": "timestamp_millis"}}
]
}
}
]
}
The difference is in the "type" attribute.
As far as I know opt2 is the correct way. Am I right? Is opt1 valid?
The second one is correct. The first one is not valid.
A record schema is something that looks like this:
{
"type": "record",
"name": <Name of the record>,
"fields": [...],
}
And for fields, it should be like this:
[
{
"name": <name of field>,
"type": <type of field>,
},
...
]
So in the case of a field which contains a record, it should always look like this:
[
{
"name": <name of field>,
"type": {
"type": "record",
"name": <Name of the record>,
"fields": [...],
}
},
...
]
The format in the first example would make it unclear if the name "field_1" was the name of the field or the name of the record.

Dynamic values in Rest API using JMeter

I have payload POST call:
{
"tenantName":"loki",
"owner":
{
"country": "india",
"firstName": "raj",
"lastName": "kumar",
"locale": "in",
"organization": "softwareag",
"phone": "9789155778",
"title": "mr",
"userName": "raraj#softwareag.com",
"email": "raraj#softwareag.com",
"password":"V2VsY29tZUAxMjM0"
},
"products": [
"cumulocity",
"b2b"
]
}
In that payload, the tenant name is unique, How to pass different values for each post call?
You can use __RandomString to randomize name, for example 5 lower case letters:
${__RandomString(5,abcdefghijklmnopqrstuvwxyz,)}
RandomString function returns a random String of length using characters in chars to use
Or load name values from CSV Data set config
You can use __groovy() function in order to call RandomStringUtils.randomAlphabetic() method like:
${__groovy(org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(4),)}
replace 4 with the number of your choice to make the random string shorter or longer
The function can be inlined directly into your request body
{
"tenantName": "${__groovy(org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(4),)}",
"owner": {
"country": "india",
"firstName": "raj",
"lastName": "kumar",
"locale": "in",
"organization": "softwareag",
"phone": "9789155778",
"title": "mr",
"userName": "raraj#softwareag.com",
"email": "raraj#softwareag.com",
"password": "V2VsY29tZUAxMjM0"
},
"products": [
"cumulocity",
"b2b"
]
}
More information: Apache Groovy - Why and How You Should Use It

How to select column with json without sending column name?

I'm setting up an API with Node and postgreSQL-node (pg), and when I query for the column in my data base that contains JSON it returns an array of objects with the columns name and the json I want to access.
My current query is:
select jsondata
from breweries
The output is:
[
{
"jsondata": {
"id": 2,
"name": "Avondale Brewing Co",
"brewery_type": "micro",
"street": "201 41st St S",
"city": "Birmingham",
"state": "Alabama",
"postal_code": "35222-1932",
"country": "United States",
"longitude": "-86.774322",
"latitude": "33.524521",
"phone": "2057775456",
"website_url": "http://www.avondalebrewing.com",
"updated_at": "2018-08-23T23:19:57.825Z",
"tag_list": []
}
},
{"jsondata": {...}},
{...}
]
My expectation is to get and array with the contents inside "jsondata" without the name of the column "jsondata", but I can't find a way to access it one level in my query.
Edit:
Here is what I expect:
[
{
"id": 2,
"name": "Avondale Brewing Co",
"brewery_type": "micro",
"street": "201 41st St S",
"city": "Birmingham",
"state": "Alabama",
"postal_code": "35222-1932",
"country": "United States",
"longitude": "-86.774322",
"latitude": "33.524521",
"phone": "2057775456",
"website_url": "http://www.avondalebrewing.com",
"updated_at": "2018-08-23T23:19:57.825Z",
"tag_list": []
},
{...},
{...}
]
I'm not sure what exact output you're expecting, but you can convert the array of dictionaries to rows and then return the jsondata values as individual rows using this:
SELECT jsonb_array_elements(jsondata)->'jsondata'
FROM breweries
Is that along the lines of what you want?
SQL Fiddle