I have to insert some data from JSON to SQL database so I use below code:
sqlQuery1 = "DECLARE #json varchar(max)='" + inputData + "';";
sqlQuery2 = "INSERT INTO [Test].[dbo].[Work] " +
"SELECT [Id], [Created], [Assignee] " +
"FROM OPENJSON(#json) "+
"WITH ([Id] int '$.id',"+
"[Created] datetimeoffset(4) '$.fields.created',"+
"[Assignee] varchar(200) '$.fields.assignee.name')";
System.out.println(sqlQuery2); stmt.addBatch(sqlQuery1);stmt.addBatch(sqlQuery2); break;
$fields.created date has format eg: "2021-03-04T07:11:40.000+0000"
I tried using different way but not able to insert above format date into SQL.
Kindly help me with this code to insert created date to db.
Thank you in advance
SQL Server expects the time zone portion of your datetimeoffset string to include the colon character, i.e.: +00:00 instead of just +0000.
You will need to extract it from JSON as a varchar/nvarchar column first so that you can insert the : character before converting it to a datetimeoffset like so:
declare #json nvarchar(max) = N'{
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id": "180",
"fields": {
"created": "2021-03-04T07:11:40.000+0000",
"assignee": {
"name": "pallavi"
}
}
}';
select *
from openjson(#json) with (
[Id] int '$.id',
[Created] varchar(29) '$.fields.created',
[Assignee] varchar(200) '$.fields.assignee.name'
) shredded
outer apply (
select [CreatedDatetimeoffset] = convert(datetimeoffset, stuff(Created, 27, 0, ':'))
) converted;
Related
I want to convert actual_arrival and actual_departure to human readable date and then see everything as a simple table. For now I'm getting an error:
Conversion failed when converting date and/or time from character string
How to do that?
Declare #json varchar(MAX) = '
{"stops":
{
"type": "stop",
"name": "stops",
"company_id": "xxx",
"actual_arrival": "20210910130000-0500",
"actual_departure": "20210910140000-0500"}
}';
SELECT *
FROM OPENJSON ( #json, '$.stops' )
WITH (
Type Varchar(50) '$.type',
Name Varchar(50) '$.name',
CompID Varchar(100) '$.company_id' ,
AcArrvl DATETIME '$.actual_arrival' ,
AcDprtr DATETIME '$.actual_departure') as j1
I think the problem is the formatting of the datetimeoffset. Also you are probably looking to convert into datetimeoffset to preserv time offset? This works for me (not that pretty but you have to reformat the string to yyyy-MM-dd hh:mm:ss-hh:mm):
Declare #json varchar(MAX) = '
{"stops":
{
"type": "stop",
"name": "stops",
"company_id": "xxx",
"actual_arrival": "20210910130000-0500",
"actual_departure": "20210910140000-0500"}
}';
SELECT
Type,
Name,
CompID,
CONVERT(DATETIMEOFFSET,
STUFF(STUFF(STUFF(STUFF(STUFF(STUFF(AcArrvl,
18,0,':'),
13,0,':'),
11,0,':'),
9,0,' '),
7,0,'-'),
5,0,'-')
) AcArrvl,
CONVERT(DATETIMEOFFSET,
STUFF(STUFF(STUFF(STUFF(STUFF(STUFF(AcDprtr,
18,0,':'),
13,0,':'),
11,0,':'),
9,0,' '),
7,0,'-'),
5,0,'-')
) AcDprtr
FROM OPENJSON ( #json, '$.stops' )
WITH (
Type Varchar(50) '$.type',
Name Varchar(50) '$.name',
CompID Varchar(100) '$.company_id' ,
AcArrvl VARCHAR(100) '$.actual_arrival' ,
AcDprtr VARCHAR(100) '$.actual_departure') as j1
I am trying to convert SQL Server results into a doubly nested JSON format.
Source SQL Server table:
ID
Name
Program
Type
Section
Director
Project
Sr Manager
PCM
Contractor
Cost Client
123
abc
qew
tyu
dd
ghghjg
hkhjk
fghfgf
gnhghj
gghgh
gghhg
456
yui
gdffgf
ghgf
jkjlkll
uiop
rtyuui
rfv
ujmk
rfvtg
efgg
Convert into doubly JSON as shown here:
[
[
{"key":"ID","value":"123"},
{"key":"Name","value":"abc"},
{"key":"Program","value":"qew"},
{"key":"Type","value":"tyu"},
{"key":"Section","value":"dd"},
{"key":"Director","value":"ghghjg"},
{"key":"Project","value":"hkhjk"},
{"key":"Sr Manager","value":"fghfgf"},
{"key":"PCM","value":"gnhghj"},
{"key":"Contractor","value":"gghgh"},
{"key":"Cost Client","value":"gghhg"}
],
[
{"key":"ID","value":"456"},
{"key":"Name","value":"yui"},
{"key":"Program","value":"gdffgf"},
{"key":"Type","value":"ghgfjhjhj"},
{"key":"Section","value":"jkjlkll"},
{"key":"Director","value":"uiop"},
{"key":"Project","value":"rtyuui"},
{"key":"Sr Manager","value":"rfv"},
{"key":"PCM","value":"ujmk"},
{"key":"Contractor","value":"rfvtg"},
{"key":"Cost Client","value":"efgg"}
]
]
Any help would be greatly appreciated.
Edit:
I started with this by rewriting the "FOR JSON AUTO" so that I can add "Key" "Value" text somehow.
But because my table has space in the column name, FOR XML PATH('') giving invalid XML identifier as required by FOR XML error.
that is when I thought of taking community help.
Create PROCEDURE [dbo].[GetSQLtoJSON] #TableName VARCHAR(255)
AS
BEGIN
IF OBJECT_ID(#TableName) IS NULL
BEGIN
SELECT Json = '';
RETURN
END;
DECLARE #SQL NVARCHAR(MAX) = N'SELECT * INTO ##T ' +
'FROM ' + #TableName;
EXECUTE SP_EXECUTESQL #SQL;
DECLARE #X NVARCHAR(MAX) = '[' + (SELECT * FROM ##T FOR XML PATH('')) + ']';
SELECT #X = REPLACE(#X, '<' + Name + '>',
CASE WHEN ROW_NUMBER() OVER(ORDER BY Column_ID) = 1 THEN '{'
ELSE '' END + Name + ':'),
#X = REPLACE(#X, '</' + Name + '>', ','),
#X = REPLACE(#X, ',{', '}, {'),
#X = REPLACE(#X, ',]', '}]')
FROM sys.columns
WHERE [Object_ID] = OBJECT_ID(#TableName)
ORDER BY Column_ID;
DROP TABLE ##T;
SELECT Json = #X;
END
Sample data:
CREATE TABLE [dbo].[Test1](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Col1] [int] NOT NULL,
[Col 2] varchar(50)
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Test1] ON
GO
INSERT [dbo].[Test1] ([ID], [Col1], [Col 2]) VALUES (1, 0,'ABCD')
GO
INSERT [dbo].[Test1] ([ID], [Col1] ,[Col 2]) VALUES (2, 1, 'POIU')
GO
SET IDENTITY_INSERT [dbo].[Test1] OFF
GO
You can use the following code:
Inside an APPLY, unpivot the columns as key/value pairs...
... and aggregate using FOR JSON PATH
Use STRING_AGG to do another aggregation.
SELECT '[' + STRING_AGG(CAST(v.json AS nvarchar(max)), ',') + ']'
FROM T
CROSS APPLY (
SELECT *
FROM (VALUES
('ID', CAST(ID AS nvarchar(100))),
('Name', Name),
('Program', Program),
('Type', [Type]),
('Section', Section),
('Director', Director),
('Project', Project),
('Sr Manager', [Sr Manager]),
('PCM', PCM),
('Contractor', Contractor),
('Cost Client', [Cost Client])
) v([key], value)
FOR JSON PATH
) v(json)
db<>fiddle
You cannot use FOR JSON again, because then you will get ["json": [{"key" : ...
first of all check this link you can find what you want
format-query-results-as-json-with-for-json-sql-server
but in your case you can try this
SELECT
ID,Name,Program,Type,Section,
Director,Project,Sr,Manager,PCM,Contractor,Cost,Client
FROM table
FOR JSON AUTO;
check the link there is more sample so it can help you
I have a JSON string that I am trying to import into my SQL Server database using the OPENJSON WITH but I am having issues because I think the JSON "field names" contain a forward slash.
What else would I need to do in order to get the start and end values? At the moment I just get NULLS...
DECLARE #JSONText NVarChar(max) = '[{
"Labour Resource Name": "ABC Consulting",
"Start Date/Time": "2020-07-06T06:30:00",
"End Date/Time": "2020-07-06T10:30:00"
}]'
SELECT *
FROM OPENJSON (#JSONText)
WITH ([Labour Resource Name] NVarChar(512),
[Start Date/Time] NVarChar(50),
[End Date/Time] NVarChar(50)
)
You don't have to mangle your output column aliases, instead you can specify JSON paths for all of them:
DECLARE #JSONText NVarChar(max) = '[{
"Labour Resource Name": "ABC Consulting",
"Start Date/Time": "2020-07-06T06:30:00",
"End Date/Time": "2020-07-06T10:30:00"
}]';
SELECT j.*
FROM OPENJSON (#JSONText)
WITH (
[LabourResourceName] nvarchar(512) '$."Labour Resource Name"',
[StartDateTime] nvarchar(50) '$."Start Date/Time"',
[EndDateTime] nvarchar(50) '$."End Date/Time"'
) j;
DECLARE #JSONText NVarChar(max) = '[{
"Labour Resource Name": "ABC Consulting",
"Start Date/Time": "2020-07-06T06:30:00",
"End Date/Time": "2020-07-06T10:30:00"
}]'
SELECT *
FROM OPENJSON (REPLACE(#JSONText, N'Date/Time', N'Date\/Time'))
WITH ([Labour Resource Name] NVarChar(512),
[Start Date/Time] NVarChar(50),
[End Date/Time] NVarChar(50)
)
Wrap the json field name in double quotes:
Before:
ecommerce nvarchar(max) '$.special-characters',
After:
ecommerce nvarchar(max) '$."special-characters"',
I just want to receive a json data and use it's fields as a table column for another queries.
I'm trying to make the value in the key "nameProperty" into a column in a table, and the value of the keys "newValue"fill the rows of that column.
For example:
i get a json file like this
{
"operation":{
"ID":"ABC",
"KinshipDescription":"--"
},
"fields":[
{
"property":{
"nameProperty":"ID",
"oldValue":"",
"newValue":"123456",
"confirmed":"false",
"labelProperty":"ID",
"oldValueDescription":"",
"newValueDescription":"123456"
}
},
{
"property":{
"nameProperty":"Name",
"oldValue":"",
"newValue":"John",
"confirmed":"false",
"labelProperty":"Name",
"oldValueDescription":"",
"newValueDescription":"John"
}
}
]
}
I want to extract the objects on the list "fields", but i only can make them an row for key, and another row for values like the script below makes.
DECLARE #jsonObj NVARCHAR(MAX)
--Set a result in
SET #jsonObj = (select JSON_Query(data, '$.fields') from table where id = 'ABC')
select * from openjson(#jsonObj)
with (Property nvarchar(255) '$.property.nameProperty',
newValue nvarchar(50) '$.property.newValue')
and I have no idea how I can do this
the results of this script is something like this
ID 123456
Name John
and the results that i want to see is
ID Name --column name, not a row
123456 John
The quickest (thought-wise, not necessarily performance) way I can come up with on this is using dynamic SQL. In fact, I'm pretty certain you'll have to use it.
Here's an example that can get you moving. You can run this in SSMS.
DECLARE #json NVARCHAR(MAX) =
'{
"operation":{
"ID":"ABC",
"KinshipDescription":"--"
},
"fields":[
{
"property":{
"nameProperty":"ID",
"oldValue":"",
"newValue":"123456",
"confirmed":"false",
"labelProperty":"ID",
"oldValueDescription":"",
"newValueDescription":"123456"
}
},
{
"property":{
"nameProperty":"Name",
"oldValue":"",
"newValue":"John",
"confirmed":"false",
"labelProperty":"Name",
"oldValueDescription":"",
"newValueDescription":"John"
}
}
]
}';
-- Variable to hold the column/values.
DECLARE #cols VARCHAR(MAX) = '';
-- Generate the column/value pairs.
SELECT
#cols = #cols
+ CASE WHEN ( LEN( #cols ) > 0 ) THEN ', ' ELSE '' END -- add comma if needed.
+ '''' + Properties.newValue + ''' AS [' + Properties.nameProperty + '] '
FROM OPENJSON( #json, '$.fields' ) WITH (
property NVARCHAR(MAX) '$.property' AS JSON
)
CROSS APPLY (
SELECT * FROM OPENJSON( property ) WITH (
nameProperty VARCHAR(50) '$.nameProperty',
oldValue VARCHAR(50) '$.oldValue',
newValue VARCHAR(50) '$.newValue',
confirmed VARCHAR(50) '$.confirmed',
labelProperty VARCHAR(50) '$.labelProperty',
oldValueDescription VARCHAR(50) '$.oldValueDescription',
newValueDescription VARCHAR(50) '$.newValueDescription'
)
) AS Properties;
-- Execute column/value pairs as dynamic SQL.
EXEC ( 'SELECT ' + #cols );
Which returns:
+--------+------+
| ID | Name |
+--------+------+
| 123456 | John |
+--------+------+
If you were to PRINT #cols you would see
'123456' AS [ID] , 'John' AS [Name]
A few quick notes:
Performance may vary.
Values are quoted but can be CAST if needed.
Included all 'property' fields in CROSS APPLY for example. Only specify what is needed.
Note the use of NVARCHAR when using AS JSON
May want to consider OUTER APPLY if there's potential for no 'property' present.
How can I read value from json file in that field name contains space using OPENJSON in Sql Server 2016. See the below code:
DECLARE #json NVARCHAR(MAX)
SET #json = N'{ "full name" : "Jayesh Tank"}';
SELECT * FROM OPENJSON(#json) WITH ( [name] [varchar](60) '$.full name')
Also another sample code in that space is after field name.
SET #json = N'{ "name " : "abc"}';
SELECT * FROM OPENJSON(#json) WITH ( [name] [varchar](60) '$.name')
'$.name' will return null.Is there way to read this value?
Generally it is a bad idea to use spaces in the attribute name.
I would leave out the [ ] from your OPENJSON name and varchar(60) - source MSDN OPENJSON.
Now to actually answer your question:
You need to format your attribute with double quotes in the WITH clause:
#DECLARE #json NVARCHAR(MAX);
SET #json=N'{ "full name" : "Jayesh Tank"}';
SELECT * FROM OPENJSON(#json) WITH (name varchar(60) '$."full name"')
for the second one:
SET #json = N'{ "name " : "abc"}';
SELECT * FROM OPENJSON(#json) WITH ( name varchar(60)'$."name "')
JSON_VALUE(c.value,'$.Serial Number') as [Serial Number] is throwing an error with a space. How do I resolve the space in the field name using JSON_VALUE .
by itself '$.Full Name' is not a valid json, but adding '$."Full Name"' the json becomes valid