Remove the Elements which in another string - sql-server

I have a column Airports where it has values as 'DXB,KWI,COK'.
I need to compare these column value with a string like 'DXB,LHR' remove the column value which in comma separated string?
After checking with string I want to update the column value as 'KWI,COK'.?
Any solutions
Airports |id
_____________________
dxb,cok,kwi |1
cok,dxb |2
kwi,dxb |3
Airport column id 1 will to update as 'COK,DXB' remove dxb which is in compared comma separated value?

Try to use REPLACE function:
CREATE TABLE #Test(
Airports varchar(256),
id int
)
INSERT #Test(Airports,id)VALUES('dxb,cok,kwi',1)
INSERT #Test(Airports,id)VALUES('cok,dxb',2)
INSERT #Test(Airports,id)VALUES('kwi,dxb',3)
INSERT #Test(Airports,id)VALUES('kwi,dxb,zxc',4)
INSERT #Test(Airports,id)VALUES('dxb',5)
INSERT #Test(Airports,id)VALUES('aaa,bbb',6)
SELECT *,REPLACE(REPLACE(REPLACE(Airports,'dxb,',''),',dxb',''),'dxb','')
FROM #Test
UPDATE #Test
SET
Airports=REPLACE(REPLACE(REPLACE(Airports,'dxb,',''),',dxb',''),'dxb','')
WHERE Airports LIKE '%dxb%'
SELECT *
FROM #Test
DROP TABLE #Test

ALTER FUNCTION [dbo].[SplitString]
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
ALTER FUNCTION [dbo].[DistinctSplitString]
(
#string1 nvarchar(max),
#string2 nvarchar(max),
#chars character(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
INSERT INTO #output
select SP1.Item from dbo.SplitString(#string1,#chars) as SP1
LEFT JOIN dbo.SplitString(#string2,#chars) as SP2
ON SP1.Item = SP2.Item
WHERE sp2.Item IS NULL
RETURN
END
By using this two function we can easily get values

Related

SQL Executing store procedure multiple times

I have a stored procedure that will delete from ausers table based on an ID I pass in. If I was to delete multiple users or a range of the IDs, is there a way i can do this?
The IDs are Ints.
You have to create one function which is used to split string and you can pass parameter with separated comma
Function
---------------
CREATE FUNCTION SplitString
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
GO
Store Procedure
----------------------
DECLARE #CustomerID VARCHAR(50) = '1,2,3'
DELETE FROM Customer WHERE CustomerID in (SELECT Item
FROM dbo.SplitString(#CustomerID, ','))
Hope this help you :)

How to use parameters in Stored procedure on in Clause

I need to update a table by using Stored procedure.
In that Stored Procedure i am using a IN Clause for some specific rows,Here i use a string which is having a value exacltly like this ='AC101','AC102','AC103'
eg:
string Recipt = "'AC101','AC102','AC103'";
Also My stored procedured query is
#PaymentDate nvarchar(MAX),
#ReciptNo nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
update Monthly_Payment set Payment_Date = #PaymentDate where Recipt_No in (#ReciptNo );
END
It's executing the query but not update the records which is mentioned in string
Note:
If i use normal query it's updated successfully.
ex:
update Monthly_Payment set Payment_Date = #PaymentDate where Recipt_No in (#ReciptNo );
Please update on this.
DECLARE #MonthlyPayment TABLE
(
PaymentDate NVARCHAR(10) ,
ReceiptNo NVARCHAR(50)
);
INSERT INTO #MonthlyPayment
( PaymentDate, ReceiptNo )
VALUES ( '2018-01-13', 'AC102' ),
( '2018-01-11', 'AC101' ),
( '2018-02-10', 'AC103' );
DECLARE #PaymentDate NVARCHAR(MAX)= '2018-05-04' ,
#ReceiptNo NVARCHAR(50)= N'AC101,AC102,AC103';
UPDATE #MonthlyPayment
SET PaymentDate = #PaymentDate
WHERE ReceiptNo IN ( SELECT value
FROM STRING_SPLIT(#ReceiptNo, ',') );
/*The STRING_SPLIT function is available only under compatibility level 130. If your database compatibility level is lower than 130, SQL Server will not be able to find and execute */
SELECT PaymentDate ,
ReceiptNo
FROM #MonthlyPayment;
Try this answer this will definitely work for you
Step 1 : first create this function. just run the following code
CREATE FUNCTION [dbo].[StringSplitToTable]
(
#Input NVARCHAR(MAX) ,
#Character CHAR(1)
)
RETURNS #Output TABLE ( Item VARCHAR(500) )
AS
BEGIN
DECLARE #StartIndex INT ,
#EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output
( Item
)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
Step 2:
This Update query will be like the following
NOTE: MAKE SURE DATA SHOULD BE IN THIS FORMAT #ReciptNo='AC101,AC102,AC103'
update Monthly_Payment set Payment_Date = #PaymentDate where Recipt_No in (select item from StringSplitToTable(#ReciptNo,',') );

Return first five numbers form string within UDF

I am working on SQL Server (2005,2008 & 2012)
I wanna extract first five numbers from varchar column via using UDF
Input:
rrr123ddd4567ddd19828www2
123hhhsss124ss18762s
qq12349wsss12376ss
Output:
19828
18762
12349
My Trail is as following:
DECLARE
#myString VARCHAR(1000),
#temp VARCHAR(100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #myString = 'rrr123ddd4567ddd19828www2'
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #temp = Replace (#temp,',','''),(''')
Select #temp = '(''' + #temp + ''')'
Create table #temp
(
col1 varchar(100)
)
SET #ExecuteInsert = 'insert into #temp values ' + #temp
Execute sp_executesql #ExecuteInsert
select top 1 col1 from #temp
where LEN(col1) = 5
drop table #temp
-- Output >> 19828
The previous query is working well with string input , but I wanna using this code within UDF to could using it with columns.
if I used the previous query within UDF, the following error is raising:
Cannot access temporary tables from within a function.
EDIT
if I used Table variable , I get the next error:
Only functions and some extended stored procedures can be executed
from within a function.
any help will be greatly appreciated.
CREATE FUNCTION udfTest
(
-- Add the parameters for the function here
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE
#Result int,
#myString VARCHAR(1000),
#temp VARCHAR(100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #myString = 'rrr123ddd4567ddd19828www2'
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #temp = Replace (#temp,',','''),(''')
Select #temp = '(''' + #temp + ''')'
Declare #tempTable TABLE
(
col1 varchar(100)
)
insert into #tempTable SELECT #temp
select top 1 #Result=col1 from #tempTable
where LEN(col1) = 5
return #Result
END
GO
Here you are my answer of my question , hope helps others.
The objective is creating UDF function for using it with columns, not only fixed values.
The approach is using SplitString instead of sp_executesql
for splitting a comma separated string and loop it's values in table.
Demo:-
Create table DummyTable
( col1 varchar (100))
go
Insert into DummyTable values ('rrr123ddd4567ddd19828www2')
Insert into DummyTable values ('123hhhsss124ss18762s')
Insert into DummyTable values ('qq12349wsss12376ss')
go
/*
SplitString via Mudassar Khan
http://www.aspsnippets.com/Articles/Split-and-convert-Comma-Separated-Delimited-String-to-Table-in-SQL-Server.aspx
*/
Create FUNCTION SplitString
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
GO
-------------------------------------
-------------------------------------
-------------------------------------
/*
My Own Function
*/
Create FUNCTION udfGetFirstFiveNumbers
(
#myString VARCHAR(1000)
)
RETURNS varchar(100)
AS
BEGIN
DECLARE
#temp VARCHAR(100),
#result Varchar (100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #result = Item
FROM dbo.SplitString(#temp, ',')
where len(Item) = 5
return #result
END
GO
-- Test
select col1, dbo.udfGetFirstFiveNumbers(col1) as result
from DummyTable
Result:-

Multiple-value in one parameter

CREATE FUNCTION [dbo].[func_1]
(
#ListNum AS nvarchar(MAX)
)
RETURNS #t TABLE
(
col_1 nvarchar(MAX)
)
AS
BEGIN
INSERT #t
SELECT col_1
FROM table_name
WHERE col_2 IN (#ListNum)
RETURN
END
When I pass only one value in paramater (for example : 1) the function correctly works but how can I pass multiple value (for example : 1,2,3,4,5). I get the following error :
Procedure execution failed
42000 - [SQL Server]Error converting data type nvarchar to bigint.
Is there a simple way to solve this?
Hi you can try like this,
CREATE FUNCTION Splitstring (#Input NVARCHAR(MAX),
#Character CHAR(1))
RETURNS #Output TABLE (
Item NVARCHAR(1000))
AS
BEGIN
DECLARE #StartIndex INT,
#EndIndex INT
SET #StartIndex = 1
IF Substring(#Input, Len(#Input) - 1, Len(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE Charindex(#Character, #Input) > 0
BEGIN
SET #EndIndex = Charindex(#Character, #Input)
INSERT INTO #Output
(Item)
SELECT Substring(#Input, #StartIndex, #EndIndex - 1)
SET #Input = Substring(#Input, #EndIndex + 1, Len(#Input))
END
RETURN
END
GO
CREATE FUNCTION [dbo].[Func_1] (#ListNum AS NVARCHAR(MAX))
RETURNS #t TABLE (
col_1 NVARCHAR(MAX))
AS
BEGIN
INSERT #t
SELECT p.col1
FROM dbo.Splitstring(#ListNum, ',') s
JOIN Table_Name t
ON t.col2 = s.Item
RETURN
END
DECLARE #var VARCHAR(100)='1,2,3,4'
SELECT *
FROM dbo.Func_1(#var)
Introduce one more function called split string. It will return the comma separated list as a table. Join the comma separated table with your actual table. This will gives the result.
For versions 2008+ using table separated values can assist where the calling procedure can construct the table and you are able to create a table type. If you must pass comma (or other character separated values) in a single string then you will need to separate the comma delimited string into a result set of its own.
The XML method works well when your string doesn't contain any special XML characters such as angle brackets <> - how-to-split-a-comma-separated-value-to-columns
I think this will work for your adjusted function;
CREATE FUNCTION [dbo].[func_1]
(
#ListNum AS nvarchar(MAX)
)
RETURNS #t TABLE
(
col_1 nvarchar(MAX)
)
AS
BEGIN
DECLARE #S varchar(max),
#Split char(1),
#X xml
SELECT #S = #ListNum,
#Split = ','
SELECT #X = CONVERT(xml,' <root> <s>' + REPLACE(#S,#Split,'</s> <s>') + '</s> </root> ')
INSERT #t
SELECT col_1
FROM table_name
WHERE col_2 IN (SELECT [Value] = T.c.value('.','varchar(20)')
FROM #X.nodes('/root/s') T(c))
RETURN
END

How to insert a comma separated values to the column to a SQL table in a order same as passing order?

i written a code like below to insert a comma separated values to the tempTble.It is working but i need the values to be entered in a order same as am passing it to query.But here number are arranged in a numerical order and string values arranged according to alphabetical order .Example '7,6,5,1,2,Jack,Ana,Micky' but it is inserted to column in a order of '1,2,5,6,7,Ana,Jack,Micky'.
Can you please provide answer for this.
Thank you in advance
ALTER PROCEDURE [dbo].[usp_GetValuesFromBillingSystem]
(
#BillingSystemCode VARCHAR(max)
)
AS
BEGIN
DECLARE #planID varchar(max) = Null ;
SET #planID= #BillingSystemCode
DECLARE #tempTble Table (planID varchar(50) NULL);
while len(#planID ) > 0
begin
insert into #tempTble (planID ) values(left(#planID , charindex(',', #planID +',')-1))
set #planID = stuff(#planID , 1, charindex(',', #planID +','), '')
end
select * from #tempTble
END
www.aspdotnet-suresh.com/2013/07/sql-server-split-function-example-in.html
CREATE FUNCTION dbo.Split(#String nvarchar(4000), #Delimiter char(1))
RETURNS #Results TABLE (Items nvarchar(4000))
AS
BEGIN
DECLARE #INDEX INT
DECLARE #SLICE nvarchar(4000)
-- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
-- ERO FIRST TIME IN LOOP
SELECT #INDEX = 1
WHILE #INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT #INDEX = CHARINDEX(#Delimiter,#STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF #INDEX !=0
SELECT #SLICE = LEFT(#STRING,#INDEX - 1)
ELSE
SELECT #SLICE = #STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO #Results(Items) VALUES(#SLICE)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT #STRING = RIGHT(#STRING,LEN(#STRING) - #INDEX)
-- BREAK OUT IF WE ARE DONE
IF LEN(#STRING) = 0 BREAK
END
RETURN
END

Resources