Separate substring by comma SQL Server - sql

I have string from which I have to extract substring and query on their values.
declare #str varchar(max)
#str='Hello,world,continent,nation,city'
select * from mytable
where col_word in(SELECT REPLACE(#str,',',''','''))
The sub query
SELECT REPLACE(#str,',',''',''')
results in
Hello,'world','continent','nation','city
I want the above result be enclosed by single quotes so that it can work for IN
But this returns only for first col_word value Hello which is first substring in #str.
What should I do ?

Try this:
You cannot make part of your query as string. We have to make the whole query as a string, then execute it with EXEC() command.. or sp_executesql stored procedure. The latter is recommended.
declare #str varchar(max);
select #str='Hello,world,continent,nation,city';
SELECT #str=''''+REPLACE(#str,',',''',''')+''''
exec('select * from mytable where col_word in('+#str +')')

Try this:
declare #str varchar(max)
declare #pattern varchar(max)
SET #str='Hello,world,continent,nation,city'
SELECT REPLACE(#str,',',''',''')
SET #pattern = REPLACE('Hello,world,continent,nation,city', ',', ''',''')
EXEC('select * from mytable where col_word in(''' + #pattern + ''')')

Related

How to use a dynamic WHERE clause in my SQL CTE query?

I've a question about my SQL CTE construction. I'm working with Azure Data Factory and a Stored Procedure in my database. What I want to do is:
Return my data from my view to Azure Data Factory in JSON format.
Return the data filtered dynamically in the WHERE clause based on my ObjectCode in my view in JSON format.
-> To test step 2 I tried with a statical declared ObjectCode
But the single quote does not work right in the WHERE clause. I tried some things with REPLACE, CHAR(39) and double the quotes. Like they said here, here and here
Step 1 I've finished succesfull with this code:
BEGIN
DECLARE #TABLE TABLE(RESULT NVARCHAR(MAX))
DECLARE #QUERY NVARCHAR(MAX) = '
;WITH x(Params) as
(
SELECT * FROM [Schema].[View] FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
Select * from x
'
Insert #TABLE
EXEC (#QUERY)
Select ',"pipelineParameters": ' + LEFT(RESULT,LEN(RESULT)-1) + '}' as Params from #TABLE;
END
This query above gave me the right result. But, now I need to make a change for Step 2. I need to filter with the WHERE clause in the query.
So, I tried:
DECLARE #TABLE TABLE(RESULT NVARCHAR(MAX))
DECLARE #ObjectCode NVARCHAR(MAX) = 'Objectname'
DECLARE #QUERY NVARCHAR(MAX) = '
;WITH x(Params) as
(
SELECT * FROM [Schema].[View]
WHERE Objectcode = REPLACE(#ObjectCode, '''', '')
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
Select * from x
'
Insert #TABLE
EXEC (#QUERY)
Select ',"pipelineParameters": ' + LEFT(RESULT,LEN(RESULT)-1) + '}' as Params from #TABLE;
But when I run these query I get this error:
Does anyone know what I can improve here so I can get it working?
Does this do what you want?
Insert #TABLE
exec sp_executesql #QUERY, N'#ObjectCode nvarchar(max)', #ObjectCode=#ObjectCode;
As written, I would expect a syntax error when the query is run because of this WHERE clause:
WHERE Objectcode = REPLACE(#ObjectCode, '', ')
I think you intend:
DECLARE #QUERY NVARCHAR(MAX) = '
WITH x(Params) as (
SELECT *
FROM [Schema].[View]
WHERE Objectcode = REPLACE(#ObjectCode, '''''''', '''')
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
Select *
from x';
Quoting things in dynamic SQL is always verbose. You can print out #Query to see if it is really what you intend.
'
Thanks Gordon, the first one works for me:
Insert #TABLE
exec sp_executesql #QUERY, N'#ObjectCode nvarchar(max)', #ObjectCode=#ObjectCode;

Using a comma-separated parameter in an IN clause

I have 'param1, param2, parma3' coming from SSRS to a stored procedure as a varchar parameter: I need to use it in a query's IN clause but then need to change its format like this first:
select *
from table1
where col1 in('param1', 'param2', 'param3')
What is the best way to reformat the parameter without creating functions and parameter tables?
Try this one, Just need to add commas at the beginning and at the end of #params string.
Declare #params varchar(100) Set #params = ',param1,param2,param3,'
Select * from t
where CHARINDEX(','+cast(col1 as varchar(8000))+',', #params) > 0
SQL FIDDLE
you can use split function and use it as in following way
here my split fnSplitString return splitdata
select * from tb1 where id in(select splitdata from dbo.fnSplitString((select col1 from tb12 where id=3),','))
create FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output(splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
If you are using SQL 2016 and above string_split you can use.
-- #param is where you keep your comma separated values example:
declare #param = 'param1,param2,param3'
select * from table1 where col1 in (select TRIM(value) from string_split(#param,',')
More information about string_split check offical documemt
Furthermore, TRIM() is used to trim values from white spaces.
We can use STRING_SPLIT() in SQL SERVER
DECLARE #params varchar(max)= 'param1,param2,param3'
SELECT *
FROM table1
WHERE col1 IN (SELECT value FROM STRING_SPLIT( #params , ','))
"Best way" is arguable, but one classic approach that remains without "creating functions and table parameters" is to simply employ dynamic SQL in the stored procedure:
-- FORNOW: local to act as the SP param and arg
declare #values varchar(100) = 'param1, param2, param3'
-- Add opening and closing single quotes, then quotes around each
-- comma-separated list item.
select #values = '''' + REPLACE(#values, ', ', ''', ''') + ''''
-- FORNOW: for clarity/debugging
print #values
--'param1', 'param2', 'param3'
-- Run the desired query as dynamic SQL.
DECLARE #sql as nvarchar(250);
SET #sql = 'select * from table1 where col1 in (' + #values + ')';
EXEC sp_executesql #sql;
This assumes a couple things, though:
That commas in the list of values are followed by a space. Variations on this solution can address deviations in this respect of course, but it is important to be aware of this assumption.
That the comma-separated values do not themselves have commas in them – unlikely but worth mentioning since whether values will satisfy this constraint sometimes goes unconsidered.
Load the Params into a string and execute as an sql :
declare #param varchar(1000) = 'param1, param2, parma3'
declare #sql varchar(4000)
select #sql =
'select *
from table1
where col1 in(''' + replace(#param,',',''',''') + ''')'
-- print #sql -- to see what you're going to execute
exec sp_executesql #sql
DECLARE #params varchar(max) = '1,2,3,4'
SELECT * FROM table2 WHERE colId IN (SELECT value FROM SPLIT(#params,','))
Base on id we can find.

Getting output in a variable from dynamic SQL

I am using a dynamic sql i.e.
DECLARE #searchstring VARCHAR(500)
DECLARE #str VARCHAR(MAX)
SELECT #str = 'SELECT * FROM Table1 WHERE ' + #searchstring
EXECUTE #str
What I need is I want to select one column value from above dynamic sql to pass in a different SP
Let's say I need ID column value and pass it to another sp named GetAnotherData #Ids. How can I do that?
well you can go with Alexander Fedorenko example, but if you don't want to create any temp tables, you can use output xml parameter to pass your ids:
declare #stmt nvarchar(max), #Data xml, #searchstring nvarchar(max)
select #stmt = '
select #Data = (
select id
from Table1
where ' + #searchstring + '
for xml raw(''Data'')
)
'
exec sp_executesql
#stmt = #stmt,
#params = N'#Data xml output',
#Data = #Data output
select
T.C.value('#id', 'int') as id
from #Data.nodes('Data') as T(C)
sql fiddle demo
The following example creates a user-defined table type that has one Id column. Further the INSERT #RetIds EXEC(#STR) statement fills the parameter list, and then passes the values to a stored procedure
CREATE TYPE RetIds AS TABLE
(
Id int
)
DECLARE #searchstring varchar(500) = 'AND SearchCol = 1'
DECLARE #str varchar(max)
SELECT #str ='SELECT Id FROM dbo.test6 WHERE 1 = 1 ' + #searchstring
DECLARE #RetIds AS RetIds
INSERT #RetIds
EXEC(#str)
EXEC dbo.ExecIds #RetIds
See demo on SQLFiddle

Group and concatenate many rows to one

I want to "concatenate" all the "Text"-rows into one single row and get one row as a result. Is this even possible? I use MSSQL Server 2005.
Use FOR XML PATH:
SELECT [Text]+' ' AS 'text()' FROM _table FOR XML PATH('')
Another option - use string concatenation:
DECLARE #s nvarchar(max)
SELECT #s = ISNULL(#s, '') + t + ' ' FROM _table OPTION (MAXDOP 1)
SELECT #s
Please note that the latter one isn't guaranteed to work, afaik, officially the behaviour of "#s = #s + ..." for multi-row resultset is undefined.
MAXDOP 1 hint is used here to prevent the optimizer from creating a parralel execution plan, as this will yield an incorrect result for sure.
I believe you're looking for something like this:
DECLARE #string nvarchar(max)
SET #string = N''
SELECT #string = #string + [Text] + N' ' FROM [YourTable]
SELECT #string
This will concatenate all of the values for the [Text] column into a single variable. You can then select the variable to retrieve all of the values in a single row.
Something like:
DECLARE #result varchar(max)
SELECT #result = COALESCE(#result + ' ','') +[Text] FROM [Table]
SELECT #result

Get the results of sp_helptext as a single string

I'm running a query using "EXEC sp_helptext Object", but it returns multiple lines with a column name Text. I'm trying to concatenate that value into a single string but I'm having trouble trying to figure out the best way to do it using T-SQL.
You can try something like this
DECLARE #Table TABLE(
Val VARCHAR(MAX)
)
INSERT INTO #Table EXEC sp_helptext 'sp_configure'
DECLARE #Val VARCHAR(MAX)
SELECT #Val = COALESCE(#Val + ' ' + Val, Val)
FROM #Table
SELECT #Val
This will bring back everything in one line, so you might want to use line breaks instead.
Assuming SQL Server 2005 and above (which is implied by varchar(max) in astander's answer), why not simply use one of these
SELECT OBJECT_DEFINITION('MyObject')
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('MyObject')
This is not very glamorous, but it works ...
DECLARE #Table TABLE(
Val VARCHAR(MAX)
)
INSERT INTO #Table EXEC sp_helptext 'sp_configure'
DECLARE #Val VARCHAR(MAX)
SET #Val = ''
SELECT #Val = #Val + REPLACE(REPLACE(REPLACE(Val, CHAR(10), ''), CHAR(13), ''), CHAR(9), '')
FROM #Table
-- Replaces line breaks and tab keystrokes.
SELECT #Val