Query a table with json format - sql

I would like to know how can I read with a sql query a table like that:
(this is just an example)
id,date,information
1,2018-26-02,{[{"iteration_number":0,"data":{"name":"Toto",values:{"PV":78,"SV":20,"TV":19},"state":"ok"},{"iteration_number":1,"data":{"name":"Baba",values:{"PV":68,"SV":10,"TV":11},"state":"ok"}}}]}
For example, to select the date of the first record, I will write: "SELECT date FROM table1 WHERE id=1;
But if I just would like the name of the iteration number 0 ? (Toto)
Say me if I'm not understandable.
Thanks for your response.
Simon

In MSSQL there is a JSON_VALUE function you can use for this:
More documentation can be found here.
DECLARE #temp_table TABLE
(
id INT NOT NULL IDENTITY(1, 1),
date DATETIME NOT NULL,
information VARCHAR(MAX) NOT NULL
);
INSERT INTO #temp_table
(date, information)
VALUES
(GETDATE(), '[{"iteration_number":1,"data":{"name":"Toto",values:{"PV":78,"SV":20,"TV":19},"state":"ok"},{"iteration_number":1,"data":{"name":"Baba",values:{"PV":68,"SV":10,"TV":11},"state":"ok"}}}]');
SELECT date, JSON_VALUE(information,'$[0].data.name') AS Name
FROM #temp_table

Related

How do I create a variable/parameter that is a string of values in SQL SSMS that I can use as a substitute in my where clause?

This may be a very basic question, but I have been struggling with this.
I have a SSMS query that I'll be using multiple times for a large set of client Ids. Its quite cumbersome to have to amend the parameters in all the where clauses every time I want to run it.
For simplicity, I want to convert a query like the one below:
SELECT
ID,
Description
From TestDb
Where ID in ('1-234908','1-345678','1-12345')
to a query of the format below so that I only need to change my variable field once and it can be applied across my query:
USE TestDb
DECLARE #ixns NVARCHAR(100)
SET #ixns = '''1-234908'',''1-345678'',''1-12345'''
SELECT
ID,
Description
From TestDb
Where ID IN #ixns
However, the above format doesn't work. Can anyone help me on how I can use a varchar/string variable in my "where" clause for my query so that I can query multiple IDs at the same time and only have to adjust/set my variable once?
Thanks in advance :D
The most appropriate solution would be to use a table variable:
DECLARE #ixns TABLE (id NVARCHAR(100));
INSERT INTO #ixns(id) VALUES
('1-234908'),
('1-345678'),
('1-12345');
SELECT ID, Description
FROM TestDb
WHERE ID IN (SELECT id FROM #ixns);
You can load ids to temp table use that in where condition
USE TestDb
DECLARE #tmpIDs TABLE
(
id VARCHAR(50)
)
insert into #tmpIDs values ('1-234908')
insert into #tmpIDs values ('1-345678')
insert into #tmpIDs values ('1-12345')
SELECT
ID,
Description
From TestDb
Where ID IN (select id from #tmpIDs)
The most appropriate way is to create a table type because it is possible to pass this type as parameters.
1) Creating the table type with the ID column.
create type MyListID as table
(
Id int not null
)
go
2) Creating the procedure that receives this type as a parameter.
create procedure MyProcedure
(
#MyListID as MyListID readonly
)
as
select
column1,
column2
...
from
MyTable
where
Id in (select Id from #MyListID)
3) In this example you can see how to fill this type through your application ..: https://stackoverflow.com/a/25871046/8286724

Select row just inserted without using IDENTITY column in SQL Server 2012

I have a bigint PK column which is NOT an identity column, because I create the number in a function using different numbers. Anyway, I am trying to save this bigint number in a parameter #InvID, then use this parameter later in the procedure.
ScopeIdentity() is not working for me, it saved Null to #InvID, I think because the column is not an identity column. Is there anyway to select the record that was just inserted by the procedure without adding an extra ID column to the table?
It would save me a lot of effort and work if there is a direct way to select this record and not adding an id column.
insert into Lab_Invoice(iID, iDate, iTotal, iIsPaid, iSource, iCreator, iShiftID, iBalanceAfter, iFileNo, iType)
values (dbo.Get_RI_ID('True'), GETDATE(),
(select FilePrice from LabSettings), 'False', #source, #user, #shiftID, #b, #fid, 'Open File Invoice');
set #invID = CAST(scope_identity() AS bigint);
P.S. dbo.Get_RI_ID('True') a function returns a bigint.
Why don't you use?
set #invId=dbo.Get_RI_ID('True');
insert into Lab_Invoice(iID,iDate,iTotal,iIsPaid,iSource,iCreator,iShiftID,iBalanceAfter,iFileNo,iType)
values(#invId,GETDATE(),(select FilePrice from LabSettings),'False',#source,#user,#shiftID,#b,#fid,'Open File Invoice');
You already know that big id value. Get it before your insert statement then use it later.
one way to get inserted statement value..it is not clear which value you are trying to get,so created some example with dummy data
create table #test
(
id int
)
declare #id table
(
id int
)
insert into #test
output inserted.id into #id
select 1
select #invID=id from #id

writing from a SQL view to a Table

Hello I've got this SQL View (Namely Login_Monitor) that I've created using a number of table joins
What I'm wanting to do now is to use a few columns in this View to write to a seperate table that I've created.
But Im gettiing Null values written to table instead of actual data.
This is how I created my destination table
create table MS_Login_Monitor
(date date,
time time,
USERID char(15),
COMPANY_NAME char(65),
LOGIN_DATE_TIME datetime,
TIME_SINCE_LAST_ACTION int,
)
This is the query I used to write view data to destination table
declare #date date
declare #time time
declare #USERID char(20)
declare #COMPANY_NAME char(65)
declare #LOGIN_DATE_TIME datetime
declare #TIME_SINCE_LAST_ACTION nchar(7)
set #date = CURRENT_TIMESTAMP
set #time = CURRENT_TIMESTAMP
select * from Login_Monitor
INSERT INTO DYNAMICS..MS_Login_Monitor (date, time,USERID, COMPANY_NAME, LOGIN_DATE_TIME, TIME_SINCE_LAST_ACTION)
VALUES (#date, #time,#USERID,#COMPANY_NAME, #LOGIN_DATE_TIME, #TIME_SINCE_LAST_ACTION)
could someone explain please why I get NULL values written to table please or if there are errors in my SQL query.
Thanks
You can try something like this;
INSERT INTO DYNAMICS..MS_Login_Monitor (date, time,USERID, COMPANY_NAME, LOGIN_DATE_TIME, TIME_SINCE_LAST_ACTION)
select #date, #time, X, Y.....(use actual column names of view) from Login_Monitor
You dont need other parameters.

SQL automatically rounding off values

I have two table. First table(Table1) use to get the records and second table(Table2) used to insert first table record into it. But I am little bit confused after getting result.
In table 1 and table 2 column "Amount" have same data type i.e nvarchar(max)
Table1
Id Amount
1 Null
2 -89437.43
2 -533.43
3 22403.88
If I run this query
Insert into Table2(Amount)
Select Amount from Table1
Then get result like this, I don't know why values are automatically rounded off
Table2
Id Amount
1 Null
2 -89437.4
2 -533.43
3 22403.9
SQL Server will round float values when converting back and to from string types.
And then you have the fun bits of empty string being 0, as well other strange effects
SELECT CAST(CAST('' AS float) AS nvarchar(MAX))
SELECT CAST(CAST('0.E0' AS float) AS nvarchar(MAX))
Use decimal.
If you need to store "blank" (how does this differ from NULL?) use a separate bit column to allow that extra value
Here is good explanation about your question.
Eigher you explicitly give float or decimal or numeric(xx,x) (x means numeric value)
Then it will convert as the data, other wise it round off the last value.
Insert into Table2(Amount)
Select cast(Amount as numeric(18,2) --or , cast (Amount as float)
from Table1
Check this link:-
TSQL Round up decimal number
In my case I was doing the conversion to the correct data type but had decimal(18,0) for the column in the table. So make sure the decimal places are represented properly for the column decimal(18,2).
Perhaps it's your query tool that's truncating to 8 characters.
Check the actual fields lengths to see if the problem is really in the database:
SELECT LEN(Amount)
FROM Table2
WHERE Amount LIKE '%-89437.%'
Unreproducible. Running this script on SQL Server 2012:
DECLARE #T1 TABLE ([Amount] nvarchar(max) NULL);
DECLARE #T2 TABLE ([Amount] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount])
VALUES (NULL),('-89437.43'),('-533.43'),('22403.88');
Insert into #T2(Amount)
Select Amount from #T1;
SELECT * FROM #T2;
Produces this result:
Amount
NULL
-89437.43
-533.43
22403.88
The problem you describe does not exist.
This will show you the problem:
DECLARE #T1 TABLE ([Amount123456789] money NULL);
DECLARE #T2 TABLE ([Amount123456789] nvarchar(max) NULL);
INSERT INTO #T1 ([Amount123456789])
VALUES (NULL),('-89437.43123'),('-533.43456'),('22403.88789'),(22403.88789);
Insert into #T2(Amount123456789)
Select Amount123456789 from #T1;
SELECT * FROM #T1;
SELECT * FROM #T2;

SQL Query Finding From Table DataType Declaration

I got some serial keys to find in sql database, such as “A-B-C”,”D-E-F”,”G-H-I”,”J-K-L” and they are stored in tblTemp using ntext data type. These above keys may store in three columns, colA, colB and colC (sometimes store in one column and the rest are null). Sometimes, two serial keys can find in one column (e.g. A-B-C;D-E-F) using “;” seperated. so i wrote the following sql query.
Declare #sa TABLE(var1 nvarchar(Max));
Insert INTO #sa(var1) VALUES (N’A-B-C’);
Insert INTO #sa(var1) VALUES (N’D-E-F’);
Insert INTO #sa(var1) VALUES (N’G-H-I’);
Insert INTO #sa(var1) VALUES (N’J-K-I’);
SELECT * FROM tblTemp
WHERE colA IN (SELECT var1 FROM #sa);
so i got the following error message.
The data types ntext and nvarchar(max) are incompatible in the equal to operator.
I still need to find for colB and colC. How should write query for this kind of situation?
all suggestions are welcome.
CAST/CONVERT (msdn.microsoft.com) your var1 to NTEXT type in your query so that the types are compatible.
SELECT
*
FROM
tblTemp
WHERE
colA IN (
SELECT
CAST(var1 AS NTEXT)
FROM
#sa
);
You have to convert/cast your search term as an appropriate data type, in this case text.
Try this:
Declare #sa TABLE(var1 nvarchar(Max));
Insert INTO #sa(var1) VALUES (N’A-B-C’);
Insert INTO #sa(var1) VALUES (N’D-E-F’);
Insert INTO #sa(var1) VALUES (N’G-H-I’);
Insert INTO #sa(var1) VALUES (N’J-K-I’);
SELECT *
FROM tblTemp t
WHERE EXISTS (SELECT 1
FROM #sa s
WHERE t.colA like cast('%'+s.var1+'%' as text)
OR t.colB like cast('%'+s.var1+'%' as text)
OR t.colC like cast('%'+s.var1+'%' as text)
);
Since all suggestions are welcome.
How about change the datatype on tblTemp to NVARCHAR(MAX)?
NTEXT was deprecated with the introduction of NVARCHAR(MAX) in 2005.
ALTER TABLE tblTemp ALTER COLUMN colA NVARCHAR(MAX)