I want to convert the following funciton creation to work in MySql
CREATE FUNCTION dbo.DistinctList
(
#List VARCHAR(MAX),
#Delim CHAR
)
RETURNS
VARCHAR(MAX)
AS
BEGIN
DECLARE #ParsedList TABLE
(
Item VARCHAR(MAX)
)
DECLARE #list1 VARCHAR(MAX), #Pos INT, #rList VARCHAR(MAX)
SET #list = LTRIM(RTRIM(#list)) + #Delim
SET #pos = CHARINDEX(#delim, #list, 1)
WHILE #pos > 0
BEGIN
SET #list1 = LTRIM(RTRIM(LEFT(#list, #pos - 1)))
IF #list1 <> ''
INSERT INTO #ParsedList VALUES (CAST(#list1 AS VARCHAR(MAX)))
SET #list = SUBSTRING(#list, #pos+1, LEN(#list))
SET #pos = CHARINDEX(#delim, #list, 1)
END
SELECT #rlist = COALESCE(#rlist+',','') + item
FROM (SELECT DISTINCT Item FROM #ParsedList) t
RETURN #rlist
END
I found this function at http://blog.sqlauthority.com/2009/01/15/sql-server-remove-duplicate-entry-from-comma-delimited-string-udf/
I don't know why people have down graded my question.
Anyway I was able to come up with the answer.
Delimiter //
CREATE FUNCTION DistinctList
(
List TEXT,
Delim CHAR
)
RETURNS
TEXT
BEGIN
DECLARE list1 TEXT;
DECLARE Pos INT;
DECLARE rList TEXT;
DROP TEMPORARY TABLE IF EXISTS ParsedList;
Create temporary table if not exists ParsedList
(
Item VARCHAR(60)
) ENGINE=MEMORY;
SET list = CONCAT(list, Delim);
SET pos = length(SUBSTRING_INDEX(list, delim, 1));
WHILE (pos > 0) DO
SET list1 = SUBSTRING(list, 1, pos);
IF list1 <> '' THEN
INSERT INTO ParsedList VALUES (list1);
END IF;
SET list = SUBSTRING(list, pos+2);
SET pos = length(SUBSTRING_INDEX(list, delim, 1));
END WHILE;
SELECT GROUP_CONCAT(DISTINCT Item) FROM ParsedList INTO rlist;
RETURN rlist;
END//
Delimiter ;
Related
CREATE DEFINER=`root`#`localhost` PROCEDURE `TestExampl2_SP`(in Array_Value varchar(255))
begin
declare i int default 0;
declare loopcount int default 0;
declare arrayChar varchar(50) ;
declare isexist int(10) default 0;
declare existString varchar(50);
declare notexistString varchar(50) ;
set loopcount=( select LENGTH(Array_Value) - LENGTH(REPLACE(Array_Value, ',', '')));
while i<=loopcount do
SET i = i + 1;
set arrayChar =(
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(Array_Value, ',', i), ',', -1));
set isexist=(select count(*) from emp
where ename=arrayChar);
if(isexist >0 ) then
select CONCAT_WS(',',existString,arrayChar) into existString;
else
select CONCAT_WS(',',notexistString,arrayChar) into notexistString;
end if;
END WHILE;
select notexistString;
END
This is my Procure when i execute this Procedure whith input call TestExampl2_SP('a,m,n,x,y,z') i am getting notexistString ='x,y,z' but insetd of this i want result row wise i.e i have to split by comma
like this :
**value**
x
y
z
please suggest me how i will implement this .
You can follow below code to split string in sql.
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
And check using
SELECT Item FROM dbo.SplitString('Apple,Mango,Banana,Guava', ',')
I have a stored procedure where input is a comma separated string say '12341,34567,12446,12997' and it is not sure that the input string always carries numerical data. It may be '12341,34as67,12$46,1we97' so I need to validate them and use only the valid data in query.
Say my query is (Where the column OrderCode is int type)
select * from dbo.DataCollector where OrderCode in (12341,34567,12446,12997)
or only the valid data if other are invalid
select * from dbo.DataCollector where OrderCode in (12341)
For such situation what would be a good solution.
One way that works also in SQl-Server 2005 would be to create a split-function, then you can use ISNUMERIC to check if it's a number:
DECLARE #Input VARCHAR(MAX) = '12341,34as67,12$46,1we97'
SELECT i.Item FROM dbo.Split(#Input, ',')i
WHERE IsNumeric(i.Item) = 1
Demo
Your complete query:
select * from dbo.DataCollector
where OrderCode in ( SELECT i.Item FROM dbo.Split(#Input, ',')i
WHERE IsNumeric(i.Item) = 1 )
Here is the split-function which i use:
CREATE FUNCTION [dbo].[Split]
(
#ItemList NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #ItemTable TABLE (Item VARCHAR(250))
AS
BEGIN
DECLARE #tempItemList NVARCHAR(MAX)
SET #tempItemList = #ItemList
DECLARE #i INT
DECLARE #Item NVARCHAR(4000)
SET #i = CHARINDEX(#delimiter, #tempItemList)
WHILE (LEN(#tempItemList) > 0)
BEGIN
IF #i = 0
SET #Item = #tempItemList
ELSE
SET #Item = LEFT(#tempItemList, #i - 1)
INSERT INTO #ItemTable(Item) VALUES(#Item)
IF #i = 0
SET #tempItemList = ''
ELSE
SET #tempItemList = RIGHT(#tempItemList, LEN(#tempItemList) - #i)
SET #i = CHARINDEX(#delimiter, #tempItemList)
END
RETURN
END
Edit according to the comment of Damien that ISNUMERIC has it's issues. You can use this function to check if it's a real integer:
CREATE FUNCTION dbo.IsInteger(#Value VarChar(18))
RETURNS Bit
AS
BEGIN
RETURN IsNull(
(Select Case When CharIndex('.', #Value) > 0
Then Case When Convert(int, ParseName(#Value, 1)) <> 0
Then 0
Else 1
End
Else 1
End
Where IsNumeric(#Value + 'e0') = 1), 0)
END
Here is another example with damien's "bad" input which contains £ and 0d0:
Demo
I have varchar values like below
72,73,74
I try to split as a comma after that i want to convert to int above values.Than i want to match Id with my User Table.
CREATE FUNCTION Fn_MyFunction(#MyUserIdValues VARCHAR(100))
RETURNS VARCHAR(300) AS
BEGIN
DECLARE #Result VARCHAR(300) = ''
Select UserName From UserTable
Where MyUserIdValues=UserIdValues
RETURN #Result
#Result must be like below in one column
Joe,Michael,Ricky
Any help will be appreciated.
Thanks.
The classic way of doing this...
/*
create table Users
(
id int,
name nvarchar(max)
)
insert into Users
values
(72, 'Joe'),
(73, 'Michael'),
(74, 'Ricky'),
(75, 'Manny'),
(76, 'Bob')
*/
CREATE FUNCTION dbo.Fn_MyFunction(#IdValues VARCHAR(100))
RETURNS NVARCHAR(max) AS
BEGIN
DECLARE #Result NVARCHAR(max);
DECLARE #delimiter as nchar = ',';
WHILE LEN(#IdValues) <> 0
BEGIN
Declare #CurrentId int;
If CHARINDEX(#delimiter, #IdValues) = 0
begin
Set #CurrentId = cast(#IdValues as int);
Set #IdValues = ''
End
Else
begin
Set #CurrentId = cast(left(#IdValues, charindex(#delimiter, #IdValues) -1) as int)
Set #IdValues = Substring(#IdValues, charindex(#delimiter, #IdValues) +1, len(#IdValues))
End
select #Result = Isnull(#Result + ',', '') + Isnull((Select Name From Users Where Id=#CurrentId),'(unknown)')
END
RETURN #Result
END
GO
Select dbo.Fn_MyFunction('72,73,74')
--Joe,Michael,Ricky
Select dbo.Fn_MyFunction('72,0,74')
--Joe,(unknown),Ricky
Select dbo.Fn_MyFunction('72,73,72,74,74')
--Joe,Michael,Joe,Ricky,Ricky
GROUP_CONCAT and FIND_IN_SET might be a handy for you.
Try this:
SELECT GROUP_CONCAT(UserName)
FROM UserTable
WHERE FIND_IN_SET(MyUserIdValues,'72,73,74');
I had found solution for splitting string and inserting it in a table
GO
/****** Object: UserDefinedFunction [dbo].[Split] Script Date: 10/03/2013 11:45:16 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Split] (
#InputString VARCHAR(8000),
#Delimiter VARCHAR(50)
)
RETURNS #Items TABLE (
Item int
)
AS
BEGIN
IF #Delimiter = ' '
BEGIN
SET #Delimiter = ','
SET #InputString = REPLACE(#InputString, ' ', #Delimiter)
END
IF (#Delimiter IS NULL OR #Delimiter = '')
SET #Delimiter = ','
DECLARE #Item VARCHAR(8000)
DECLARE #ItemList VARCHAR(8000)
DECLARE #DelimIndex INT
SET #ItemList = #InputString
SET #DelimIndex = CHARINDEX(#Delimiter, #ItemList, 0)
WHILE (#DelimIndex != 0)
BEGIN
SET #Item = SUBSTRING(#ItemList, 0, #DelimIndex)
INSERT INTO #Items VALUES (#Item)
-- Set #ItemList = #ItemList minus one less item
SET #ItemList = SUBSTRING(#ItemList, #DelimIndex+1, LEN(#ItemList)-#DelimIndex)
SET #DelimIndex = CHARINDEX(#Delimiter, #ItemList, 0)
END -- End WHILE
IF #Item IS NOT NULL -- At least one delimiter was encountered in #InputString
BEGIN
SET #Item = #ItemList
INSERT INTO #Items VALUES (#Item)
END
-- No delimiters were encountered in #InputString, so just return #InputString
ELSE INSERT INTO #Items VALUES (cast(#InputString as int))
RETURN
END -- End Function
Select UserName From UserTable where MyUserIdValues in(Select Item from Split('72,73,74',','))
//Call function Split using last query
Check this out, it will solve your problem and it simple and perfect method
Select Username from UserTable where MyUserIdValues IN ' + '('+ #Id +')'
My attempt (i think it's a little neater):
create function dbo.fn_UserNames(#ids varchar(max))
returns varchar(max) as
begin
set #ids = #ids + ','
declare #id table (Id int)
while(#ids != '') begin
insert into #id
select i
from (select substring(#ids, 1, charindex(',', #ids, 0) - 1) i) a
where i != ''
if #ids like '%,%'
set #ids = substring(#ids, charindex(',', #ids, 0) + 1,
len(#ids) - charindex(',', #ids, 0))
else
set #ids = ''
end
declare #ret varchar(max)
select #ret = isnull(#ret, '') + a.UserName + ','
from adhoc.UserTable a
join #id b on a.UserId = b.Id
return #ret
end
Hi you can try this one also.
CREATE FUNCTION [DBO].[FN_SPLIT] ( #STRSTRING VARCHAR(MAX))
RETURNS #NAME TABLE (NAME VARCHAR(MAX))
AS
BEGIN
DECLARE #USERID TABLE(ID INT)
DECLARE #USERS TABLE (ID INT , NAME VARCHAR(50))
INSERT INTO #USERS VALUES (72,'A'),(73,'B'),(74,'C')
;WITH STR_CTE(_START, _STOP) AS
(
SELECT 1, CHARINDEX(',' , #STRSTRING )
UNION ALL
SELECT CAST(_STOP + 1 AS INT), CHARINDEX(',' ,#STRSTRING , CAST((_STOP + 1) AS INT))
FROM
STR_CTE
WHERE _STOP > 0
)
INSERT INTO #USERID (ID)
SELECT
SUBSTRING(#STRSTRING , _START, CASE WHEN _STOP > 0 THEN _STOP -_START ELSE 4000 END) AS ID
FROM STR_CTE
DECLARE #STRNAME VARCHAR(MAX)
SELECT
#STRNAME = COALESCE(#STRNAME+',','') + U.NAME
FROM
#USERID UD
INNER JOIN
#USERS U ON UD.ID = U.ID
INSERT INTO #NAME
SELECT #STRNAME
RETURN;
END
I have a long string.I want to check throughout this string for consecutive 15 letters if there is no space i have to manually put a space in sql server. Can any one pls help??
For eg. my string is 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ'
then it should appear like 'ABCDEFGHIJKLMNOP QRSTUVWXYZABCDE FGHIJKLMNOPQRST UVWXYZ'
#dcp1986: I tried with your function as below.
SELECT dbo.UF_StringSplitter('HeloEveryonehru Howslyfgoingonn HaveaGoodDayGoodMorning')
But an unexpected split occured. I think your function must be modified as below for the correct result:
IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_StringSplitter'))
DROP FUNCTION UF_StringSplitter
GO
CREATE FUNCTION UF_StringSplitter (
#psCSString VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #sTemp VARCHAR(MAX)
DECLARE #tTemp VARCHAR(MAX)
SET #tTemp=''
WHILE LEN(#psCSString)>15
BEGIN
SET #sTemp = LEFT(LTRIM(#psCSString), 15)
SET #psCSString = LTRIM(SUBSTRING(#psCSString,16, LEN(#psCSString)))
IF #psCSString LIKE ' %'
SET #tTemp=#tTemp+#sTemp
ELSE
SET #tTemp=#tTemp+#sTemp+' '
END
SET #tTemp=#tTemp+#psCSString
RETURN #tTemp
END
You could use a function like this
IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_StringSplitter'))
DROP FUNCTION UF_StringSplitter
GO
CREATE FUNCTION UF_StringSplitter
(
#psCSString VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #sTemp VARCHAR(MAX)
DECLARE #tTemp VARCHAR(MAX)
SET #tTemp=''
WHILE LEN(#psCSString)>15
BEGIN
SET #sTemp = LEFT(#psCSString, 15)
SET #psCSString = SUBSTRING(#psCSString,16, LEN(#psCSString))
IF #psCSString LIKE ' %'
SET #tTemp=#tTemp+#sTemp
ELSE
SET #tTemp=#tTemp+#sTemp+' '
END
SET #tTemp=#tTemp+#psCSString
RETURN #tTemp
END
Go
Here i have hard coded the splitting value, and you can use the function
UPDATE mytable SET mycol=dbo.UF_StringSplitter(mycol)
I don't know how to do it on a single statement, but you can create a sql function something like this
create function AddStuffCharacterInLength (#original nvarchar(100), #take int, #stuff varchar(100))
returns nvarchar(200)
AS
BEGIN
declare #result nvarchar(200)
declare #len int
declare #skip int
set #len = len(#original)
set #result = ''
set #skip = (#take * -1) + 1
while #len > 0
begin
set #result = #result + substring(#original, #skip + #take, #take)
set #len = #len - #take
set #skip = #skip + #take
if #len > 0
set #result = #result + ' '
end
RETURN #result
END
And use it like this
select dbo.AddStuffCharacterInLength ('ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ',15, ' ')
And the output should be
----------------------------------------------------------------------------------------------------
ABCDEFGHIJKLMNO PQRSTUVWXYZABCD EFGHIJKLMNOPQRS TUVWXYZ
(1 row(s) affected)
can anybody help me to write the following MS-SQL sp to MySQL sp,
use of this:
CREATE PROCEDURE sp_InputWork
#_DelimitedString nvarchar(MAX)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #_DataRow nvarchar(MAX)
DECLARE #_DescriptionOfWorkDone nvarchar(MAX)
DECLARE #_TemporaryStorage nvarchar(MAX)
DECLARE #_QTY int
DECLARE #_Total int
DECLARE #_CurrentField int
WHILE CHARINDEX(';', #_DelimitedString) > 0
BEGIN
SET #_DataRow = CAST(SUBSTRING(#_DelimitedString, 0, CHARINDEX(';', #_DelimitedString)) AS nvarchar(MAX))
SET #_CurrentField = 1
WHILE CHARINDEX(',', #_DataRow) > 0
BEGIN
SET #_TemporaryStorage = CAST(SUBSTRING(#_DataRow, 0, CHARINDEX(',', #_DataRow)) AS nvarchar(MAX))
IF #_CurrentField = 1
SET #_QTY = CAST(#_TemporaryStorage AS int)
IF #_CurrentField = 2
SET #_DescriptionOfWorkDone = #_TemporaryStorage
IF #_CurrentField = 3
SET #_Total = CAST(#_TemporaryStorage AS int)
SET #_DataRow = SUBSTRING(#_DataRow, CHARINDEX(',', #_DataRow) + 1, LEN(#_DataRow))
SET #_CurrentField = #_CurrentField + 1
END
INSERT INTO tblWorkDone (QTY, DescriptionOfWorkDone, Total) VALUES (#_QTY, #_DescriptionOfWorkDone, #_Total)
SET #_DelimitedString = SUBSTRING(#_DelimitedString, CHARINDEX(';', #_DelimitedString) + 1, LEN(#_DelimitedString))
END
END
I have changed the SP to Mysql
BEGIN
DECLARE _DataRow VARCHAR(21000);
DECLARE _DescriptionOfWorkDone VARCHAR(21000);
DECLARE _TemporaryStorage VARCHAR(21000) ;
DECLARE _QTY int;
DECLARE _Total int;
DECLARE _CurrentField int;
WHILE INSTR(_DelimitedString, ';') >0 DO
SET _DataRow = CAST(SUBSTRING(_DelimitedString, 1, INSTR(_DelimitedString,';' )) AS CHAR);
SET _CurrentField = 1;
WHILE INSTR(_DataRow,',' ) > 0 DO
SET _TemporaryStorage = CAST(SUBSTRING(_DataRow, 1, INSTR(_DataRow,',' )-1) AS CHAR);
IF _CurrentField = 1 then
SET _QTY = CAST(_TemporaryStorage AS UNSIGNED);
end if;
IF _CurrentField = 2 then
SET _DescriptionOfWorkDone = _TemporaryStorage;
end if;
IF _CurrentField = 3 then
SET _Total = CAST(_TemporaryStorage AS UNSIGNED) ;
end if;
SET _DataRow = SUBSTRING(_DataRow, INSTR( _DataRow,',') + 1, LENGTH(_DataRow));
SET _CurrentField = _CurrentField + 1;
END while;
INSERT INTO tblWorkDone (QTY, DescriptionOfWorkDone, Total) VALUES (_QTY, _DescriptionOfWorkDone, _Total);
SET _DelimitedString = SUBSTRING(_DelimitedString, INSTR(_DelimitedString,';' ) + 1, LENGTH(_DelimitedString));
END WHILE;END
Data inserted
CALL `sp_InputWork`('1,TEST,100,;2,TEST1,200,;3,TEST3,300,;')
Successfully looped and inserted to Mysql Table