How to produce JSON strings from SQL Server queries via TSQL? - sql-server

I wanted to know if there is any function or something to convert the SQL select query result to JSON string format?
For example, SQL select query result is,
current target
-----------------
500 1000
1500 2000
JSON result:
[{"current":500,"target":1000},{"current":1500,"target":2000}]
Any ideas will be helpful.
Thanks.

SQL Fiddle
MS SQL Server 2008 Schema Setup:
Query 1:
DECLARE #TABLE TABLE ([current] INT, [target] INT)
INSERT INTO #TABLE VALUES
(500 , 1000),
(1500 , 2000)
SELECT '[' + STUFF((SELECT ',{"current":' + CAST([current] AS VARCHAR(30))
+ ',"target":' + CAST([target] AS VARCHAR(30)) + '}'
FROM #TABLE
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,1,'') + ']'
Results:
[{"current":500,"target":1000},{"current":1500,"target":2000}]

You don't specify version.
In SQL Server 2016 you will be able to do something like
SELECT [current],
target
FROM YourTable
ORDER BY [current]
FOR JSON AUTO;
More details here or in the official pre release documentation

I use
SELECT
JSON_QUERY(( SELECT
[current],target
FROM YourTable
FOR JSON PATH
))
Works well with minimal effort. I generally convert the output to a List<Dictionary<string,dynamic>> in C#/.Net (if I don't have an existing model).

Related

How do i split string into 4 columns in ms sql?

Example string: " s:6:"module";s:11:"leadCapture"; "
--Note: s is not important.
I tried using string_split:
SELECT value
into temp
FROM STRING_SPLIT('s:6:"module";s:11:"leadCapture";s:6:"action";s:5:"save2";', ';');
select * from temp;
Below is the output:
Row 1: s:6:"module"
Row 2: s:11:"leadCapture"
Row 3: s:6:"action"
Row 4: s:5:"save2"
Expected Output:
6 - column 1,
module - column 2,
11 - column 3,
leadcapture - column 4.
The following code will work starting with MS SQL Server 2016:
declare #s nvarchar(max) = N's:6:"module";s:11:"leadCapture";s:6:"action";s:5:"save2";';
select row_number() over(order by r.Ordinal, v.[key]) as [RN],
v.value as [SubStringValue]
from (
select t.[key] as [Ordinal], t.value as [Value]
from openjson('["' + replace(string_escape(#s, 'json'), ';', '","') + '"]', '$') t
where t.[key] <= 1
) r
cross apply openjson('["' + replace(string_escape(r.Value, 'json'), ':', '","') + '"]', '$') v
where v.[key] > 0
order by RN;
Ugly and convoluted, but at the time of writing this is your only option if you want to do it in pure SQL in an on-prem instance. The alternatives are:
Azure SQL (both SQL Database and Managed Instance) have an improved version of the string_split() function, which accepts an additional parameter, enable_ordinal. This will add an extra column into its output containing ordinal position of substrings within a string. If you use Azure version of SQL, or somehow have SQL Server 2022, this will allow you to avoid having to deal with JSON.
CLR function. Pretty much the best solution when it comes to string manipulation in SQL Server, but can be a pain to maintain.
Cleansing by some ETL tool (SSIS, ADF, AirFlow, whatever) before the data enters the database.

How to convert to UTF-8 in SQL Server database?

i'm working on mssql server 2017.
i got table with 'name' nvarchar column with values that look like '\u039b \u041e \u0422 \u0422 \u0410'
(sequence of '\u0[number][number][number or letter]')
how do i convert them to the correct characters?
This is actually the same as JSON escaping.
You can use JSON_VALUE to get the value out, by creating a JSON array
SELECT JSON_VALUE('["' + t.name + '"]', '$[0]')
FROM YourTable t;
db<>fiddle

REGEXP_SUBSTR equivalent in SQL Server

I have an Oracle query using
SELECT REGEXP_SUBSTR('500 Oracle Parkway, Redwood Shores, CA',',[^,]+,')
FROM DUAL;
It returns the output as below:
, Redwood Shores,
I am trying to get the exact same result in SQL Server. I tried to do it as below
substring(text, patindex, length)
But I struggled with length specification.
Can you please let me know how I can achieve this is in SQL Server?
You can try below query
WITH dual AS
(
SELECT '500 Oracle Parkway, Redwood Shores, CA' AS st
)
SELECT SUBSTRING(REVERSE(SUBSTRING(REVERSE(st),
CHARINDEX(',', REVERSE(st)),
LEN(st))),
CHARINDEX(',', st),
LEN(st)) str_value
FROM dual
Below is the result which I have got
Note: with clause is just for data preparation. Just make use of the substring part in select statement
Try this:
Declare #test varchar(max)='500 Oracle Parkway, Redwood Shores, CA'
select reverse(substring(reverse(substring(#test,charindex(',',#test),len(#test))),
charindex(',',reverse(substring(#test,charindex(',',#test),len(#test)))),
len(substring(#test,charindex(',',#test),len(#test)))))

Get minimum value from columnconcat from three tables + lpad inside. MS SQL

I am working in SQL Server Managment Studio 2014.
In the project I am working on I have three tables, each containing 2 columns, one datetime with the exact date (but on time is contained) and the other one - smallint containing time (8:55 is 855 value, while for example 14:45 is 1445).
What I want to do is to get minimum value which is merged from both of those columns from all of those three tables.
What I have figure out by myself until now is:
Use lpad("U_StartTime", 0, '4') to fill values like 855 into 0855 (for exact comparison). However lpad is not recognized at my studio.
lpad is not recognized built in function
Then I can merge both columns like this:
SELECT concat("U_StartDate", ' ', "U_StartTime") FROM "TABLE1".
This is ok until I try make it with lpad.
Then I may take all values to consider like this:
SELECT concat("U_StartDate", ' ', "U_StartTime") FROM "TABLE1"
UNION
SELECT concat("U_StartDate", ' ', "U_StartTime") FROM "TABLE2"
...
And I can take MIN(column) but I do not know how to get MIN from the whole UNION SELECT (of those three tables).
Thank you in advance for any advices on my current sql problems.
edit - image for NikHil:
EDIT:
I have changed the way a bit. Now I am modifying datetime object rather than working on string comparison. As an example for someone I paste part of the code:
select DATEADD(minute, "U_StartTime"%100, DATEADD(hour, "U_StartTime"/100, "U_StartDate")) from "TABLE1"
rather than
select MIN(concat("U_StartDate", ' ', RIGHT('0000' + "U_StartTime", '4'))) from "TABLE1"
You can use RIGHT instead of lpad
SELECT RIGHT('0000' + '855', 4) -- 0855
SELECT RIGHT('0000' + '1445', 4) -- 1445
Query looks like
SELECT MIN(RIGHT('0000' + YourColumn, 4) * 1)
FROM
Tbl
may be you can try this
select data from
(
select concat("U_StartDate", ' ', "U_StartTime")as 'data' from "TABLE1"
UNION
select concat("U_StartDate", ' ', "U_StartTime")as 'data' from "TABLE2"
...
)
where data is not null
order by data asc
LIMIT 1;

convert to_char(..,'MON-YYYY') into sql server

I have the following query with plsql
SELECT to_char(add_months(l_max_date, l_rec.MON_INTERVAL),'MON-YYYY')
FROM dual
I am looking to write it with sql sever
select CONVERT(VARCHAR(2),MONTH(DATEADD(mm, MON_INTERVAL, l_max_date)))
from rec
How to write
to_char(..,'MON-YYYY') into sql server
There is no default date format in SQL Server like that. You have to come up with your own.
SELECT datename(month, getdate())
+ '-'
+ convert(nvarchar, year(getdate()))
In SQL Server 2012+ you can use the FORMAT function to format a value using the same formatting string you would use in .NET:
SELECT FORMAT(GETDATE(),'MMM-yyyy')
You could do this:
SELECT
SubString(Convert(Varchar(Max), tbl.theDate,0), 1, 3) + '-'
+ Cast(Year(tbl.theDate) As Varchar(Max))
FROM
(
select CONVERT(VARCHAR(2),MONTH(DATEADD(mm, MON_INTERVAL, l_max_date))) as theDate
from rec
) AS tbl

Resources