TSQL String modify - string

I have a problem with string.
I have a variable #Rights which looks like 'ASD,ZXC,QWE,IOP,JKL'
What I need to do is use this string in
SELECT * FROM dbo.Example
WHERE Rights IN (#Rights)
Problem is that I need to convert:
'ASD,ZXC,QWE,IOP,JKL'
to:
'ASD','ZXC','QWE','IOP','JKL'
How can I do this?

you can create a split function
CREATE FUNCTION [dbo].[Split]
(
#String NVARCHAR(4000),
#Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(#Delimiter,#String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(#Delimiter,#String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(#String,stpos,COALESCE(NULLIF(endpos,0),LEN(#String)+1)-stpos)
FROM Split
)
GO
and after you can convert the string in a temp table
DECLARE #Rights NVARCHAR(128)
SET #Rights = 'ASD,ZXC,QWE,IOP,JKL'
SELECT *
INTO #Temp
FROM dbo.Split(#Rights , ',')
and after you can use it in your query like this
SELECT * FROM dbo.Example
WHERE Rights IN (SELECT Data FROM #Temp)

You can try like this:
DECLARE #xml xml, #str varchar(100), #delimiter varchar(10)
SET #str = 'ASD,ZXC,QWE,IOP,JKL'
SET #delimiter = ','
SET #xml = cast(('<X>'+replace(#str, #delimiter, '</X><X>')+'</X>') as xml)
SELECT C.value('.', 'varchar(10)') as value FROM #xml.nodes('X') as X(C)
SQL DEMO

You can use Dynamic SQL:
LiveDemo
-- sample data
CREATE TABLE #Example(ID INT IDENTITY(1,1), Rights VARCHAR(100));
INSERT INTO #Example VALUES ('ASD'), ('ABC'), ('IOP');
DECLARE #Rights NVARCHAR(MAX) = 'ASD,ZXC,QWE,IOP,JKL';
DECLARE #sql NVARCHAR(MAX) =
N'SELECT *
FROM #Example
WHERE Rights IN (''<placeholder>'')';
SET #sql = REPLACE(#sql, '<placeholder>', REPLACE(#Rights, ',', ''','''));
-- SELECT #sql; -- for debug
EXEC dbo.sp_executesql
#sql;
But you should reconsider using Table Valued Parameter instead.

Related

MssqlRow to json string without knowing structure and data type on compile time [duplicate]

Using PostgreSQL I can have multiple rows of json objects.
select (select ROW_TO_JSON(_) from (select c.name, c.age) as _) as jsonresult from employee as c
This gives me this result:
{"age":65,"name":"NAME"}
{"age":21,"name":"SURNAME"}
But in SqlServer when I use the FOR JSON AUTO clause it gives me an array of json objects instead of multiple rows.
select c.name, c.age from customer c FOR JSON AUTO
[{"age":65,"name":"NAME"},{"age":21,"name":"SURNAME"}]
How to get the same result format in SqlServer ?
By constructing separate JSON in each individual row:
SELECT (SELECT [age], [name] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
FROM customer
There is an alternative form that doesn't require you to know the table structure (but likely has worse performance because it may generate a large intermediate JSON):
SELECT [value] FROM OPENJSON(
(SELECT * FROM customer FOR JSON PATH)
)
no structure better performance
SELECT c.id, jdata.*
FROM customer c
cross apply
(SELECT * FROM customer jc where jc.id = c.id FOR JSON PATH , WITHOUT_ARRAY_WRAPPER) jdata (jdata)
Same as Barak Yellin but more lazy:
1-Create this proc
CREATE PROC PRC_SELECT_JSON(#TBL VARCHAR(100), #COLS VARCHAR(1000)='D.*') AS BEGIN
EXEC('
SELECT X.O FROM ' + #TBL + ' D
CROSS APPLY (
SELECT ' + #COLS + '
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) X (O)
')
END
2-Can use either all columns or specific columns:
CREATE TABLE #TEST ( X INT, Y VARCHAR(10), Z DATE )
INSERT #TEST VALUES (123, 'TEST1', GETDATE())
INSERT #TEST VALUES (124, 'TEST2', GETDATE())
EXEC PRC_SELECT_JSON #TEST
EXEC PRC_SELECT_JSON #TEST, 'X, Y'
If you're using PHP add SET NOCOUNT ON; in the first row (why?).

Insert the data into the remote table from # temp table in the stored procedure

I have a stored procedure in AZURE SQL database.In that there is a requirement to insert the records into the remote table from #temp table.
As xxxx_table is in the remote database used sp_execute_remote.
below is the scenario:
Create Procedure SP1 parameter1, Parameter2
As
select Distinct B.column1, B.Column2
into #A
from (Query1
Union
Query2) B
if (select count(1) from #A) > 0
Begin
Exec sp_execute_remote #data_source_name = N'Remotedatabase',
#stmt = N'INSERT INTO [dbo].[xxxx_table]
SELECT DISTINCT
'xxx' AS 'column1',
'xxx as 'Column2',
'xxx' AS 'Column3',
'xxx' AS 'Column4',
'xxx' AS Column4
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
End
)
Getting the syntax error as below:
Incorrect syntax near 'xxx'.
Where am i going wrong? or let me know if there is another way to achieve this.
If you need to dynamically build a string in SQL single-quote the whole sentence, or use 'some text' + 'another text' to concat sentences. If you must add single quote use a double single quote ''
Example:
DECLARE #param1 int;
DECLARE #param1 VARCHAR(10);
SET #param1 = 10;
SET #param2 = 'CCDOS87'
#Stmt = 'SELECT Field1 FROM TableName WHERE Field1 = '
+ CAST(#param1 AS VARCHAR(100))
+ ' AND Field1 = '''
+ param2
+ ''''; <- This is a single '
#stmt = N'INSERT INTO [dbo].[Error_table]
SELECT DISTINCT
xxx AS column1,
xxx as Column2,
xxx AS Column3,
xxx AS Column4,
xxx AS Environment
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
update
If your tables are in different databases but in the same server use:
INSERT INTO SERVER.SCHEMA.TABLE_NAME
SELECT Something
FROM SERVER.SCHEMA.TABLE_NAME

in Tsql can i compare two string "MY String" to my string and show they are different

I need to do a query between two tables and find non matching fields
table 1 field locations has "my String"
table 2 field locations has "MY string"
they = by text but not by capitalization i need to return a false for this
Having the following data:
DECLARE #TableOne TABLE
(
[ID] TINYINT
,[Value] VARCHAR(12)
)
DECLARE #TableTwo TABLE
(
[ID] TINYINT
,[Value] VARCHAR(12)
)
INSERT INTO #TableOne ([ID], [Value])
VALUES (1,'my String')
INSERT INTO #TableTwo ([ID], [Value])
VALUES (1,'MY String')
You can use set Case Sentitive collation like this:
SELECT [TO].[Value]
,[TW].[Value]
FROM #TableOne [TO]
INNER JOIN #TableTwo [TW]
ON [TO].[ID] = [TW].[ID]
AND [TO].[Value] <> [TW].[Value]
COLLATE Latin1_General_CS_AS
or use HASH functions like this:
SELECT [TO].[Value]
,[TW].[Value]
FROM #TableOne [TO]
INNER JOIN #TableTwo [TW]
ON [TO].[ID] = [TW].[ID]
WHERE HASHBYTES('SHA1', [TO].[Value]) <> HASHBYTES('SHA1', [TW].[Value])
DECLARE #Table1 AS TABLE (FieldName VARCHAR(100))
DECLARE #Table2 AS TABLE (FieldName VARCHAR(100))
INSERT INTO #Table1 (FieldName) VALUES ('MY Location')
INSERT INTO #Table2 (FieldName) VALUES ('My Location')
With a default case insensitive collation order - Matches and returns results
SELECT * FROM #Table1 AS T1
INNER JOIN #Table2 AS T2
ON T1.FieldName = T2.FieldName
With a case sensitive collation order specified. Will not match
SELECT * FROM #Table1 AS T1
INNER JOIN #Table2 AS T2
ON T1.FieldName = T2.FieldName COLLATE Latin1_General_CS_AS_KS_WS
Microsoft article on collation

Check for a string in a CLOB

i want to search for a string in a CLOB:
some thing like id_name_2569
i get all my IDs i need like this:
select project_line_id as ID
from tbl1
where art_id in (
select art_id
from tbl2
where type = 3
);
and i search in this table:
A1 is a CLOB field
select * from tbl3 where dbms_lob.instr(A1, ID)>0;
obviously it isnt working i know, is here a way i could do this?
something like this should work:
select tbl3.*
from tbl1
inner join tbl2
on tbl2.art_id = tbl1.art_id
inner join tbl3
on tbl3.a1 like '%' || tbl1.project_line_id || '%'
where tbl2.type = 3;
You can use DBMS_LOB.instr directly as a join condition:
SELECT *
FROM (SELECT project_line_id AS ID
FROM tbl1
WHERE art_id IN (SELECT art_id FROM tbl2 WHERE TYPE = 3)) v
JOIN tbl3 ON dbms_lob.instr(tbl3.a1, v.ID) > 0

Constructing dynamic columns from parameters in Sybase

I'm trying to write a stored proc (SP) in Sybase.
The SP takes 5 varchar parameters.
Based on the parameters passed, I want to construct the column names to be selected from a particular table.
The below works:
DECLARE #TEST VARCHAR(50)
SELECT #TEST = "country"
--print #TEST
execute("SELECT DISTINCT id_country AS id_level, Country AS nm_level
FROM tempdb..tbl_books INNER JOIN
(tbl_ch2_bespoke_report INNER JOIN tbl_ch2_bespoke_rpt_mapping
ON tbl_ch2_bespoke_report.id_report = tbl_ch2_bespoke_rpt_mapping.id_report)
ON id_" + #TEST + "= tbl_ch2_bespoke_rpt_mapping.id_pnl_level
WHERE tbl_ch2_bespoke_report.id_report = 14")
but gives me multiple results:
1 1 row(s) affected.
id_level nm_level
1 4376 XYZ
2 4340 ABC
I would like to however only obtain the 2nd result.
Do I need to necessarily use dynamic SQL to achieve this?
Many thanks for your help.
--Chapax
If I'm understanding you correctly, you'd like to eliminate the "1 row(s) affected." line. If so, the "set nocount on/off" option should do the trick:
declare #something int
declare #query varchar(2000)
set nocount on
select #something=30
select #query = "SELECT * FROM a_table where id_row = " + convert(varchar(10),#something)
set nocount off
exec (#query)
or
declare #something int
declare #query varchar(2000)
set nocount on
select #something=30
set nocount off
SELECT * FROM a_table where id_row = #something
SET NOCOUNT {ON|OFF} to turn off row count messages.
Yes, you need to you dynamic SQL to change the structure or content of the result set (either the column list or the WHERE clause).

Resources