'insert into' with array - sql

I'm wondering if there's a way to use 'insert into' on a list of values. I'm trying to do this:
insert into tblMyTable (Col1, Col2, Col3)
values('value1', value2, 'value3')
So, what I'm trying to say is that value2 will be an array of strings. I'm going to put this in C# but the SQL statement is all I need really. I know I could just use a foreach and loop through my array but I figured there might be a better way sort of like the SELECT statement here: SQL SELECT * FROM XXX WHERE columnName in Array. It seems like a single query would be much more efficient than one at a time.
I'm using SQL Server 2008 R2. Thanks fellas!

You can use this type of insert statement
insert into tblMyTable (Col1, Col2, Col3)
select 'value1', value, 'value3'
from dbo.values2table('abc,def,ghi,jkl',',',-1) V
The 'value', 'value3' and 'abc,def,ghi,jkl' are the 3 varchar parameters you need to set in C# SQLCommand.
This is the supporting function required.
CREATE function dbo.values2table
(
#values varchar(max),
#separator varchar(3),
#limit int -- set to -1 for no limit
) returns #res table (id int identity, [value] varchar(max))
as
begin
declare #value varchar(50)
declare #commapos int, #lastpos int
set #commapos = 0
select #lastpos = #commapos, #commapos = charindex(#separator, #values, #lastpos+1)
while #commapos > #lastpos and #limit <> 0
begin
select #value = substring(#values, #lastpos+1, #commapos-#lastpos-1)
if #value <> '' begin
insert into #res select ltrim(rtrim(#value))
set #limit = #limit-1
end
select #lastpos = #commapos, #commapos = charindex(#separator, #values, #lastpos+1)
end
select #value = substring(#values, #lastpos+1, len(#values))
if #value <> '' insert into #res select ltrim(rtrim(#value))
return
end
GO
The parameters used are:
',' = delimiter
-1 = all values in the array, or N for just first N items
solution is above, alternatives below
Or, if you fancy, a purely CTE approach not backed by any split function (watch comments with <<<)
;WITH T(value,delim) AS (
select 'abc,def,ghi', ',' --- <<< plug in the value array and delimiter here
), CTE(ItemData, Seq, I, J) AS (
SELECT
convert(varchar(max),null),
0,
CharIndex(delim, value)+1,
1--case left(value,1) when ' ' then 2 else 1 end
FROM T
UNION ALL
SELECT
convert(varchar(max), subString(value, J, I-J-1)),
Seq+1,
CharIndex(delim, value, I)+1, I
FROM CTE, T
WHERE I > 1 AND J > 0
UNION ALL
SELECT
SubString(value, J, 2000),
Seq+1,
CharIndex(delim, value, I)+1, 0
FROM CTE, T
WHERE I = 1 AND J > 1
)
--- <<< the final insert statement
insert into tblMyTable (Col1, Col2, Col3)
SELECT 'value1', ItemData, 'value3'
FROM CTE
WHERE Seq>0
XML approach
-- take an XML param
declare #xml xml
set #xml = '<root><item>abc</item><item>def</item><item>ghi</item></root>'
insert into tblMyTable (Col1, Col2, Col3)
SELECT 'value1', n.c.value('.','varchar(max)'), 'value3'
FROM #xml.nodes('/root/item') n(c)
-- heck, start with xml string
declare #xmlstr nvarchar(max)
set #xmlstr = '<root><item>abc</item><item>def</item><item>ghi</item></root>'
insert tblMyTable (Col1, Col2, Col3)
SELECT 'value1', n.c.value('.','varchar(max)'), 'value3'
FROM (select convert(xml,#xmlstr) x) y
cross apply y.x.nodes('/root/item') n(c)
In C# code, you would only use 4 lines starting with "insert tblMyTable ..." and parameterize the #xmlstr variable.

Since you're using SQL 2008 and C# your best bet is probably to use a a table valued parameter and then join to it.
This is better than passing a comma delimited string because you don't have to worry about quotes and commas in your values.
update
Another option is to use the xml data type.
Pre-SQL 2005 another option is to pass an XML string and using OPENXML. If you use an XMLWriter to create your string it will take care of making sure your xml is valid

-- This table is meant to represent the real table you
-- are using, so when you write this replace this one.
DECLARE #tblMyTable TABLE
(
Value1 VARCHAR(200)
, Value2 VARCHAR(200)
, Value3 VARCHAR(200)
);
-- You didn't say how you were going to get the string
-- array, so I can't do anything cool with that. I'm
-- just going to say we've made a table variable to
-- put those values in. A user-defined table type
-- might be in order here.
DECLARE #StringArray TABLE
(
Value VARCHAR(200)
);
INSERT INTO #StringArray
VALUES ('Jeremy'), ('snickered'), ('LittleBobbyTables'), ('xkcd Reference');
DECLARE #Value1 VARCHAR(200) = 'This guy --->';
DECLARE #Value3 VARCHAR(200) = ' <--- Rocks!';
-- I want to cross apply the two constant values, so
-- they go into a CTE, which makes them as good as
-- in a table.
WITH VariablesIntoTable AS
(
SELECT
#Value1 AS Value1
, #Value3 AS Value3
)
-- Cross applying the array couples every row in the
-- array (which is in a table variable) with the two
-- variable values.
, WithStringArray AS
(
SELECT
VariablesIntoTable.Value1
, StringArray.Value AS Value2
, VariablesIntoTable.Value3
FROM VariablesIntoTable
CROSS APPLY #StringArray StringArray
)
INSERT INTO #tblMyTable
-- The output clause allows you to see what you just
-- inserted without a separate select.
OUTPUT inserted.Value1, inserted.Value2, inserted.Value3
SELECT
WithStringArray.Value1
, WithStringArray.Value2
, WithStringArray.Value3
FROM WithStringArray

Related

Looping through a column to check if a cast succeeds in SQL Server

I am trying to check if an entire column which is varchar and make sure it can be cast to float. I have a cursor portion like so:
DECLARE #CastFailed BIT
SET #CastFailed = (SELECT SUM(CASE WHEN TRY_CAST(#ColumnName AS FLOAT) IS NULL THEN 1
ELSE 0 END) AS CastResult)
-- Look at this
PRINT #CastFailed
IF #CastFailed > 0
BEGIN
PRINT 'ERROR: ' + #ColumnName + ' cannot be converted to FLOAT type'
SET #HasErrors = 1
END
ELSE
BEGIN
PRINT 'The cast has passed.'
END
For some reason, it is always returning 1. I already in a previous part of the cursor (not shown but above), verified that the column passed in (#ColumnName) is NOT NULL at any point.
I need to find out if all the CAST to FLOAT for #ColumnName are valid. The cursor loops through a table of columns bring in the FETCH #ColumnName one by one. What am I missing?
Easy:
DECLARE #t TABLE (txt VARCHAR(100));
INSERT #t VALUES ('ABC123'),('100.00'),('100'),('11.222.333'),('00');
DECLARE #CastFailed BIT =
(SELECT ISNULL(MAX(1),0) FROM #t AS t WHERE TRY_CAST(t.Txt AS FLOAT) IS NULL);
SELECT CastFailed = #CastFailed;
For even better performance ...
DECLARE #t TABLE (txt VARCHAR(100));
INSERT #t VALUES ('ABC123'),('100.00'),('100'),('11.222.333'),('00');
DECLARE #CastFailed BIT =
(ISNULL((SELECT TOP(1) 1 FROM
(SELECT 1 FROM #t AS t WHERE TRY_CAST(t.Txt AS FLOAT) IS NULL) AS x(x)),0));
SELECT CastFailed = #CastFailed;
Here is an option where you can avoid cursors and Dynamic SQL. It will dynamically UNPIVOT your data and return the columns which fail the conversion to float
(2008 & 2012 Compatible)
Example
Declare #YourTable Table (id int,[Col1] varchar(50),[Col2] varchar(50))
Insert Into #YourTable Values
(1,'1e6','ABC') -- This Col2 will fail Conversion
,(2,'5.5','25')
,(3,'50.25','0')
Select C.Col
,Failed = count(*)
from #YourTable A
Cross Apply ( values ( convert(xml,(Select A.* for XML RAW)) ) )B(XMLData)
Cross Apply (
Select Col = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From XMLData.nodes('//#*') xNode(xAttr)
) C
Where Col in ('Col1','Col2') -- Or you can Exclude Columns ... Where Col NOT in ('id','OtherCols','ToExclude')
and try_convert(float,value) is null
Group BY C.Col
Results
Col Failed
Col2 1

Getting error when varchar value used in select query

I have a table named 'TABLE_RELATION'. I want to use some of relation codes to filter values from a select query. But when I am trying using IN operator getting an error Conversion failed when converting the varchar value ''301','302','303','304','305','306','312'' to data type smallint.
RELATION_CODE column is type smallint.
declare #guar_tab varchar(max)
declare #guar_tab_VALUES varchar(max)
select #guar_tab=COALESCE(''+#guar_tab+''',''','''')+convert(varchar(100), RELATION_CODE) from TABLE_RELATION where RELATION_CODE>300 and RELATION_CODE<400
SET #guar_tab_VALUES=(select #guar_tab)+''''+''
SELECT #guar_tab_VALUES
select * from TABLE_RELATION where RELATION_CODE in ( #guar_tab_VALUES)
When I tried '301','302','303','304','305','306','312' instead of #guar_tab_VALUES, it is working fine.
How can I solve this issue?
Any help will be appreciated.
You cannot pass a list of values like this. You are passing in a string with a single value that happens to have a bunch of commas.
One simplish method for your code is to use dynamic SQL:
declare #sql nvarchar(max);
set #sql = '
select *
from TABLE_RELATION
where RELATION_CODE in (#guar_tab_VALUES);
';
set #sql = replace(#sql, '#guar_tab_VALUEs', #guar_tab_VALUEs);
exec sp_executesql #sql;
Looking at your query, but I feel I'm missing something. What's wrong with just:
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE > 300 AND RELATION_CODE < 400;
You're creating a delimited list of values from the table TABLE_RELATION, and then returning all those rows. There's literally no point. Based on what we have there's no need for dynamic SQL, or an IN.
We could express what you've written as:
SELECT *
FROM TABLE_RELATION TR
WHERE TR.RELATION_CODE IN (SELECT sq.RELATION_CODE
FROM TABLE_RELATION sq
WHERE sq.RELATION_CODE > 300
AND sq.RELATION_CODE < 400);
--or
SELECT *
FROM TABLE_RELATION TR
WHERE EXISTS (SELECT 1
FROM TABLE_RELATION sq
WHERE sq.RELATION_CODE > 300
AND sq.RELATION_CODE < 400
AND TR.RELATION_CODE = sq.RELATION_CODE);
As you can see, there's no need for the subquery,just put it in the main WHERE.
First of all, it's list of numbers.
So something like this
select * from table1
where col1 in ('1', '2', '3')
can be written as
select * from table1
where col1 IN (1, 2, 3)
But IN accepts a list of values, or a query that returns a list of values.
So just adding 1 string with values just won't do.
F.e. this won't work if col1 is a number.
select * from table1 where col1 IN ('1,2,3')
Because the string '1,2,3' can't be implicitly converted to a number.
Using a query could work
select * from table1
where col1 IN (select n from nums where n between 1 and 9)
If you do want use a variable that contains a list of numbers?
Then using a table variable might be for you.
DECLARE #NumTbl TABLE (n smallint primary key);
INSERT INTO #NumTbl (n)
SELECT DISTINCT RELATION_CODE
FROM TABLE_RELATION
WHERE RELATION_CODE > 300
AND RELATION_CODE < 400;
declare #guar_tab_values varchar(max);
select #guar_tab_values = concat(#guar_tab_values+', ', n) from #NumTbl order by n;
select #guar_tab_values as guar_tab_values;
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE IN (select n from #NumTbl);
In your case I would just use those criteria in the WHERE clause.
SELECT *
FROM TABLE_RELATION
WHERE RELATION_CODE > 300
AND RELATION_CODE < 400
Such requirement comes many times in many different scenarios. so why not create generic solution.
We can a create user define function to slit comma separated string and return data in form of table.
Generic User Define Function :
-- FUNCTION TO SPLIT STRINGS.
ALTER FUNCTION [dbo].[SplitString]
( #stringToSplit VARCHAR(MAX) )
RETURNS
#returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(',', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(',', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
Call use define function:
declare #guar_tab varchar(max)
declare #guar_tab_VALUES varchar(max)
select #guar_tab=COALESCE(''+#guar_tab+',','')+convert(varchar(100), RELATION_CODE) from TABLE_RELATION where RELATION_CODE>300 and RELATION_CODE<400
select * from TABLE_RELATION where RELATION_CODE in (SELECT[Name] FROM dbo.SplitString( #guar_tab))
I hope this will help you :)

Split words with a capital letter in sql

Does anyone know how to split words starting with capital letters from a string?
Example:
DECLARE #var1 varchar(100) = 'OneTwoThreeFour'
DECLARE #var2 varchar(100) = 'OneTwoThreeFourFive'
DECLARE #var3 varchar(100) = 'One'
SELECT #var1 as Col1, <?> as Col2
SELECT #var2 as Col1, <?> as Col2
SELECT #var3 as Col1, <?> as Col2
expected result:
Col1 Col2
OneTwoThreeFour One Two three Four
OneTwoThreeFourFive One Two Three Four Five
One One
If this is not possible (or if too long) an scalar function would be okay as well.
Here is a function I created that is similar to the "removing non-alphabetic characters". How to strip all non-alphabetic characters from string in SQL Server?
This one uses a case sensitive collation which actively seeks out a non-space/capital letter combination and then uses the STUFF function to insert the space. This IS a scalar UDF, so some folks will immediately say that it will be slower than other solutions. To that notion, I say, please test it. This function does not use any table data and only loops as many times as necessary, so it will likely give you very good performance.
Create Function dbo.Split_On_Upper_Case(#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare #KeepValues as varchar(50)
Set #KeepValues = '%[^ ][A-Z]%'
While PatIndex(#KeepValues collate Latin1_General_Bin, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#KeepValues collate Latin1_General_Bin, #Temp) + 1, 0, ' ')
Return #Temp
End
Call it like this:
Select dbo.Split_On_Upper_Case('OneTwoThreeFour')
Select dbo.Split_On_Upper_Case('OneTwoThreeFour')
Select dbo.Split_On_Upper_Case('One')
Select dbo.Split_On_Upper_Case('OneTwoThree')
Select dbo.Split_On_Upper_Case('stackOverFlow')
Select dbo.Split_On_Upper_Case('StackOverFlow')
Here is a function I have just created.
FUNCTION
CREATE FUNCTION dbo.Split_On_Upper_Case
(
#String VARCHAR(4000)
)
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE #Char CHAR(1);
DECLARE #i INT = 0;
DECLARE #OutString VARCHAR(4000) = '';
WHILE (#i <= LEN(#String))
BEGIN
SELECT #Char = SUBSTRING(#String, #i,1)
IF (#Char = UPPER(#Char) Collate Latin1_General_CS_AI)
SET #OutString = #OutString + ' ' + #Char;
ELSE
SET #OutString = #OutString + #Char;
SET #i += 1;
END
SET #OutString = LTRIM(#OutString);
RETURN #OutString;
END
Test Data
DECLARE #TABLE TABLE (Strings VARCHAR(1000))
INSERT INTO #TABLE
VALUES ('OneTwoThree') ,
('FourFiveSix') ,
('SevenEightNine')
Query
SELECT dbo.Split_On_Upper_Case(Strings) AS Vals
FROM #TABLE
Result Set
╔══════════════════╗
║ Vals ║
╠══════════════════╣
║ One Two Three ║
║ Four Five Six ║
║ Seven Eight Nine ║
╚══════════════════╝
If a single query is needed 26 REPLACE can be used to check every upper case letter like
SELECT #var1 col1, REPLACE(
REPLACE(
REPLACE(
...
REPLACE(#var1, 'A', ' A')
, ...
, 'X', ' X')
, 'Y', ' Y')
, 'Z', ' Z') col2
Not the most beautiful thing but it'll work.
EDIT
Just to add another function to do the same thing in a different way of the other answers
CREATE FUNCTION splitCapital (#param Varchar(MAX))
RETURNS Varchar(MAX)
BEGIN
Declare #ret Varchar(MAX) = '';
declare #len int = len(#param);
WITH Base10(N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7
UNION ALL SELECT 8 UNION ALL SELECT 9
), Chars(N) As (
Select TOP(#len)
nthChar
= substring(#param, u.N + t.N*10 + h.N*100 + th.N*1000 + 1, 1)
Collate Latin1_General_CS_AI
FROM Base10 u
CROSS JOIN Base10 t
CROSS JOIN Base10 h
CROSS JOIN Base10 th
WHERE u.N + t.N*10 + h.N*100 + th.N*1000 < #len
ORDER BY u.N + t.N*10 + h.N*100 + th.N*1000
)
SELECT #ret += Case nthChar
When UPPER(nthChar) Then ' '
Else ''
End + nthChar
FROM Chars
RETURN #ret;
END
This one uses the possibility of TSQL to concatenate string variable, I had to use the TOP N trick to force the Chars CTE rows in the right order
Build a Numbers table. There are some excellent posts on SO to show you how to do this. Populate it with values up the maximum length of your input string. Select the values from 1 through the actual length of the current input string. Cross join this list of numbers to the input string. Use the result to SUBSTRING() each character. Then you can either compare the resulting list of one-charachter values to a pre-populated table-valued variable or convert each character to an integer using ASCII() and choose only those between 65 ('A') and 90 ('Z'). At this point you have a list which is the position of each upper-case character in your input string. UNION the maximum length of your input string onto the end of this list. You'll see why in just a second. Now you can SUBSTRING() your input variable, starting at the Number given by row N and taking a length of (the Number given by row N+1) - (The number given by row N). This is why you have to UNION the extra Number on the end. Finally concatenate all these substring together, space-separated, using the algorithm of your choice.
Sorry, don't have an instance in front of me to try out code. Sounds like a fun task. I think doing it with nested SELECT statements will get convoluted and un-maintainable; better to lay it out as CTEs, IMHO.
I know that there are already some good answers out there, but if you wanted to avoid creating a function, you could also use a recursive CTE to accomplish this. It's certainly not a clean way of doing this, but it works.
DECLARE
#camelcase nvarchar(4000) = 'ThisIsCamelCased'
;
WITH
split
AS
(
SELECT
[iteration] = 0
,[string] = #camelcase
UNION ALL
SELECT
[iteration] = split.[iteration] + 1
,[string] = STUFF(split.[string], pattern.[index] + 1, 0, ' ')
FROM
split
CROSS APPLY
( SELECT [index] = PATINDEX(N'%[^ ][A-Z]%' COLLATE Latin1_General_Bin, split.[string]) )
pattern
WHERE
pattern.[index] > 0
)
SELECT TOP (1)
[spaced] = split.[string]
FROM
split
ORDER BY
split.[iteration] DESC
;
As I said, this isn't a pretty way to write a query, but I use things like this when I'm just writing up some ad-hoc queries where I would not want to add new artifacts to the database. You could also use this to create your function as an inline table valued function, which is always a tad nicer.
Please Try This:
declare #t nvarchar (100) ='IamTheTestString'
declare #len int
declare #Counter int =0
declare #Final nvarchar (100) =''
set #len =len( #t)
while (#Counter <= #len)
begin
set #Final= #Final + Case when ascii(substring (#t,#Counter,1))>=65 and
ascii(substring (#t,#Counter,1))<=90 then ' '+substring (#t,#Counter,1) else
substring (#t,#Counter,1) end
set #Counter=#Counter+1
end
print ltrim(#Final)

How to find values stored in a string not in a sql data table

For example, I have a list of values in a string:
'a', 'c', 'b', 'd'
From the data table, I got a column result like:
Result
'a'
'b'
how to write a sql which will return the values not in the table:
'c', 'd'
or
NewResult
'c'
'd'
?
It is also ok if other simple tools than sql can be used. I only need the result. Thanks!
Create FUNCTION F_SplitAsTable
(
#txt varchar(max)
)
RETURNS
#tab TABLE
(
ID Varchar(2000)
)
AS
BEGIN
declare #i int
declare #s varchar(2000)
Set #i = CHARINDEX(',',#txt)
While #i>1
begin
set #s = LEFT(#txt,#i-1)
insert into #tab (id) values (#s)
Set #txt=RIGHT(#txt,Len(#txt)-#i)
Set #i = CHARINDEX(',',#txt)
end
insert into #tab (id) values (#txt)
RETURN
END
GO
Declare #a table (Ch varchar(10))
insert into #a Values ('a')
insert into #a Values ('b')
Select s.* from dbo.F_SplitAsTable('a,b,c,d') s
left join #a a on a.Ch=s.ID
where a.Ch is NULL
Step 1: Load the search values in a temp table.
DECLARE #Search table (SearchFor char(1) not null)
INSERT #Search values ('a'), ('b'), ('c'), ('d')
(There are any number of ways to set this up, this is just the fastest to type)
Run a query like so:
SELECT SearchFor
from #Search
except select SearchIn
from DataTable
(Again, there are many forms that "in a not in b" queries can take.)
This will return everything in the first set (your temp table) that is not also found in the second set.
use the not in clause in your queries.
select myCol from myTable where myCol not in ('c','d')
select myCol from myTable where myCol not in (select myCol from otherTable)

How can I introduce multiple conditions in LIKE operator?

I want to write an SQL statement like below:
select * from tbl where col like ('ABC%','XYZ%','PQR%');
I know it can be done using OR. But I want to know is there any better solution.
This is a good use of a temporary table.
CREATE TEMPORARY TABLE patterns (
pattern VARCHAR(20)
);
INSERT INTO patterns VALUES ('ABC%'), ('XYZ%'), ('PQR%');
SELECT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
In the example patterns, there's no way col could match more than one pattern, so you can be sure you'll see each row of tbl at most once in the result. But if your patterns are such that col could match more than one, you should use the DISTINCT query modifier.
SELECT DISTINCT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
Oracle 10g has functions that allow the use of POSIX-compliant regular expressions in SQL:
REGEXP_LIKE
REGEXP_REPLACE
REGEXP_INSTR
REGEXP_SUBSTR
See the Oracle Database SQL Reference for syntax details on this functions.
Take a look at Regular expressions in Perl with examples.
Code :
select * from tbl where regexp_like(col, '^(ABC|XYZ|PQR)');
Here is an alternative way:
select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';
Here is the test code to verify:
create table tbl (col varchar(255));
insert into tbl (col) values ('ABCDEFG'), ('HIJKLMNO'), ('PQRSTUVW'), ('XYZ');
select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';
+----------+
| col |
+----------+
| ABCDEFG |
| XYZ |
| PQRSTUVW |
+----------+
3 rows in set (0.00 sec)
select * from tbl where col like 'ABC%'
or col like 'XYZ%'
or col like 'PQR%';
This works in toad and powerbuilder. Don't know about the rest
This might help:
select * from tbl where col like '[ABC-XYZ-PQR]%'
I've used this in SQL Server 2005 and it worked.
I also had the same requirement where I didn't have choice to pass like operator multiple times by either doing an OR or writing union query.
This worked for me in Oracle 11g:
REGEXP_LIKE (column, 'ABC.*|XYZ.*|PQR.*');
Even u can try this
Function
CREATE FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20))
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
Query
select * from my_table inner join (select value from fn_split('ABC,MOP',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';
If your parameter value is not fixed or your value can be null based on business you can try the following approach.
DECLARE #DrugClassstring VARCHAR(MAX);
SET #DrugClassstring = 'C3,C2'; -- You can pass null also
---------------------------------------------
IF #DrugClassstring IS NULL
SET #DrugClassstring = 'C3,C2,C4,C5,RX,OT'; -- If null you can set your all conditional case that will return for all
SELECT dn.drugclass_FK , dn.cdrugname
FROM drugname AS dn
INNER JOIN dbo.SplitString(#DrugClassstring, ',') class ON dn.drugclass_FK = class.[Name] -- SplitString is a a function
SplitString function
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER FUNCTION [dbo].[SplitString](#stringToSplit VARCHAR(MAX),
#delimeter CHAR(1) = ',')
RETURNS #returnList TABLE([Name] [NVARCHAR](500))
AS
BEGIN
--It's use in report sql, before any change concern to everyone
DECLARE #name NVARCHAR(255);
DECLARE #pos INT;
WHILE CHARINDEX(#delimeter, #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(#delimeter, #stringToSplit);
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1);
INSERT INTO #returnList
SELECT #name;
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos);
END;
INSERT INTO #returnList
SELECT #stringToSplit;
RETURN;
END;
I had to add all to Asaph's answer to make it work.
select * from tbl where col like 'ABC%'
union all
select * from tbl where col like 'XYZ%'
union all
select * from tbl where col like 'PQR%';
SELECT *
From tbl
WHERE col
LIKE '[0-9,a-z]%';
simply use this condition of like in sql and you will get your desired answer