how extract sub-string from string in sybase? - sql

With a query i get this string "Order::Resource(PPP32#BB300320LQ00J#AAAR05504)".
I want to extract string before, between and after # character as following:
id = PPP32
sub_id = BB300320LQ00J
sup_id =AAAR05504
Does anyone know how to do this?

Here's the correct solution:
declare #string varchar(50)
select #string = 'Order::Resource(PPP32#BB300320LQ00J#AAAR05504)'
declare #start int, #end int, #secondstring varchar(100)
select #start = charindex('#',#string)
select #secondstring = substring(#string, #start+1, len(#string))
select #end = charindex('#',#secondstring)
select substring(#string,charindex('(', #string)+1, #start-1-charindex('(', #string)),
substring(#string,#start+1,#end-1),
substring(#string, #start+#end+1, len(#string)-(#start+#end+1))

declare #start int, #end int, #secondstring varchar(100)
select #start = charindex('#',#string)
select #secondstring = substring(#string, #start+1, len(#string))
select #end = charindex('#',#secondstring)
select substring(#string,1, #start-1),
substring(#string,#start+1,#end-1),
substring(#string, #start+#end+1, len(#string)-#end)

Related

Getting syntax error while using table variable in table value function in SQL Server 2012

I am trying to use table variable with table value function but I am getting a syntax error. Please help me to solve this.
Here is the code:
Create FUNCTION [dbo].[SplitStrings1]
(#List NVARCHAR(MAX),
#Delimiter NVARCHAR(255))
RETURNS #Results TABLE(Col1 int)
AS
BEGIN
declare #tblHelping table (Col1 int);
declare #i int
declare #rows_to_insert int
set #i = 1
set #rows_to_insert = 1000
while #i < #rows_to_insert
begin
INSERT INTO #tblHelping VALUES (#i)
set #i = #i + 1
end
(SELECT
Number = ROW_NUMBER() OVER (ORDER BY Number),
Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(#List, Number,
CHARINDEX(#Delimiter, #List + #Delimiter, Number) - Number)))
FROM
(SELECT * FROM #tblHelping) AS n(Number)
WHERE
Number <= CONVERT(INT, LEN(#List))
AND SUBSTRING(#Delimiter + #List, Number, 1) = #Delimiter) AS y)
END
I am getting this error
A RETURN statement with a return value cannot be used in this context.
If you want to use your function then working version below. But there is better solution, please see:
Split strings the right way – or the next best way as recomended by
#SeanLange
How to split string using delimiter char using T-SQL?
How do I split a string so I can access item x?
.
CREATE FUNCTION [dbo].[SplitStrings1]
( #List NVARCHAR(MAX)
, #Delimiter NVARCHAR(255))
RETURNS #Results TABLE
(Number INT, Item NVARCHAR(MAX) )
AS
BEGIN
declare #tblHelping table (Col1 int);
declare #i int
declare #rows_to_insert int
SET #i = 1
SET #rows_to_insert = 1000
while #i < #rows_to_insert
begin
INSERT INTO #tblHelping VALUES (#i)
set #i = #i + 1
end
insert into #Results
SELECT Number = ROW_NUMBER() OVER (ORDER BY Number)
, Item
FROM (SELECT Number
, Item = LTRIM(RTRIM(SUBSTRING(#List, Number,CHARINDEX(#Delimiter, #List + #Delimiter, Number) - Number)))
FROM (SELECT * FROM #tblHelping) AS n(Number)
WHERE Number <= CONVERT(INT, LEN(#List))
AND SUBSTRING(#Delimiter + #List, Number, 1) = #Delimiter) AS y
RETURN
END
Or try something like that:
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

How to filter a string in SQL?

How to filter a string in SQL 2008?
SELECT FileName=reverse(left(reverse('\\PRODSERVER\D$\EXPORT\Data20160401.txt'),
charindex('\',reverse('\\PRODSERVER\D$\EXPORT\Data20160401.txt'),
1) - 1))
Above query returns the file name which is Data20160401.txt.
I need to fetch only the server name which is PRODSERVER.
Create a function to split your string
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
Invoke the function
select *from dbo.fnSplitString('\\PRODSERVER\D$\EXPORT\Data20160401.txt','\')
Output
PRODSERVER
D$
EXPORT
Data20160401.txt
DECLARE #path VARCHAR(50) = '\\PRODSERVER\D$\EXPORT\Data20160401.txt'
Select SubString(#path,3,(CHARINDEX('\',#path,3)-3))
Asuming the path of your file always starts with \\ you could do something like:
Filename=substring(string,0,charindex(substring(string,2,len(string)-2),'\')
Don't know if this is the exact correct syntax as I am not on a machine with any sql processor at the moment but it should do something like this:
Get the substring of your string without the leading \\
Get the location of the 3rd \ as that is where the part you dont need starts
Grab the substring from the substring you created in 1 from first position after the \\ until the position of the 3rd \

How to insert data from String in table?

I have on table PersonDetail which contains NAME and AGE as column.
I am using one application which is taking all data as String by comma and pipe separated value like 'Acton,58|Nairi,20|Sara,14|Denny,52' (Format is same as given)
I want to insert that data into table(PersonDetail) but I don't know how can I separate it as a NAME and AGE.
Some one suggested me to create function which can separate the data, But i have no idea to do it.
Can any one give me suggestion??
Thanks in advance :)
you can create Multi-statement table value function to separate the data.
you just need to insert each NAME and AGE into table type variable and after inserting you should return that table as given below.
CREATE FUNCTION UDF_InsertDataFromString
(
#dataString VARCHAR(5000)
)
RETURNS #insertedData TABLE
(
NAME VARCHAR(30),
AGE INT
)
AS
BEGIN
DECLARE #pipeIndex INT,
#commaIndex INT,
#LENGTH INT,
#NAME VARCHAR(100),
#AGE INT
SELECT #LENGTH = LEN(RTRIM(LTRIM(#dataString))),
#dataString = RTRIM(LTRIM(#dataString))
WHILE (#LENGTH <> 0)
BEGIN
SELECT #LENGTH = LEN(#dataString),
#commaIndex = CHARINDEX(',', #dataString),
#pipeIndex = CHARINDEX('|', #dataString)
IF(#pipeIndex = 0) SET #pipeIndex = #LENGTH +1
SELECT #NAME = RTRIM(LTRIM(SUBSTRING(#dataString, 1, #commaIndex-1))),
#AGE = RTRIM(LTRIM(SUBSTRING(#dataString, #commaIndex+1, #pipeIndex-#commaIndex-1))),
#dataString = RTRIM(LTRIM(SUBSTRING(#dataString, #pipeIndex+1, #LENGTH-#commaIndex-1)))
INSERT INTO #insertedData(NAME, AGE)
VALUES(#NAME, #AGE)
SELECT #LENGTH = LEN(#dataString)
END
RETURN
END
Now you can use this function while inserting data from string, you just need to pass string as parameter in function as given below.
DECLARE #personDetail TABLE(NAME VARCHAR(30), AGE INT)
INSERT INTO #personDetail(NAME, AGE)
SELECT NAME, AGE
FROM dbo.UDF_InsertDataFromString('Acton,58|Nairi,20|Sara,14|Denny,52')
SELECT NAME, AGE
FROM #personDetail
use this split func
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
and then use this query
DECLARE #x table ( id int identity(1,1)
, str varchar(50) )
DECLARE #str varchar(50)='Acton,58|Nairi,20|Sara,14|Denny,52'
INSERT INTO #x
SELECT *
FROM [dbo].[fnSplitString] (#str ,'|')
SELECT *
from #x
DECLARE #y int=(SELECT count(*)
FROM #x)
DECLARE #e varchar(50)
DECLARE #b varchar(50)
DECLARE #c varchar(50)
WHILE #y!=0
BEGIN
set #e =(SELECT str
FROM #x
where id=#y)
set #b =(substring(#e,1,(charindex(',',#e)-1)))
set #c = (substring(#e,(charindex(',',#e)+1),len(#e)-charindex(',',#e)))
INSERT INTO PersonDetail
SELECT distinct #b
, #c
FROM #x
SET #y=#y-1
END
yes you can create your own function.
just you need to apply different string function for that
https://msdn.microsoft.com/en-IN/library/ms181984.aspx

how to get the char inbetween hyphen

qa-raj-ra
I want to get raj from the above string.
Length of the character in between hyphen may vary.
If you need only part of your string, you can use the inbuilt SPLIT function in MS SQL Server.
Given the delimiter, it will split the string for you.
This query below might help return the required result;
DECLARE #string NVARCHAR(MAX),
#delimiter CHAR(1),
#start INT,
#end INT
create TABLE #output (ID int IDENTITY(1,1) PRIMARY KEY, splitdata NVARCHAR(MAX))
SET #string = 'qa-raj-ra'
SET #delimiter = '-'
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
SELECT splitdata FROM #output
WHERE ID = 2
For a better use, you can put the query into a stored procedure and use #string as parameter.
The following is a quick and nasty way of getting your result via a query (on MySQL).
SELECT LEFT(RIGHT('qa-raj-ra',LENGTH('qa-raj-ra')-INSTR('qa-raj-ra','-')),
INSTR(RIGHT('qa-raj-ra',LENGTH('qa-raj-ra')-INSTR('qa-raj-ra','-')),'-')-1);
http://sqlfiddle.com/#!2/d41d8/48020
You can replace the hard coded string with whatever you want and it will return the text between the two hyphens.
In Postgres you can use string_to_array()
select (string_to_array('qa-raj-ra', '-'))[2]

Splitting an SQL string into multiple strings

I am trying to split a single string containing multiple email address data into three variables. The strings mark the start/end of an email address with the ; character.
An example string would be:
'joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com'
The code I currently have for this is as follows:
DECLARE #Email VARCHAR(100),
#Email2 VARCHAR(100),
#Email3 VARCHAR(100)
SET #Email = 'joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com'
SET #Email2 = SUBSTRING(#Email, CHARINDEX(';', #Email)+1, LEN(#Email))
SET #Email3 = SUBSTRING(#Email, CHARINDEX(';', #Email)+1, LEN(#Email))
SET #Email = SUBSTRING(#Email, 1, CHARINDEX(';', #Email)-1)
Unfortunately this doesn't seem to work. Could someone please point out where I am going wrong and what I should do to fix my problem?
Thanks in advance.
Assuming that there will always be 3 email addresses - the following seems to work;
DECLARE #Email VARCHAR(100),
#Email2 VARCHAR(100),
#Email3 VARCHAR(100)
SET #Email = 'joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com'
SELECT #Email = LEFT(#Email, CHARINDEX(';', #Email) - 1)
,#Email2 = SUBSTRING (
#Email,
CHARINDEX(';', #Email) + 1,
CHARINDEX(';', #Email, CHARINDEX(';', #Email) + 1) - LEN(LEFT(#Email, CHARINDEX(';', #Email) )) - 1
)
,#Email3 = RIGHT(#Email, CHARINDEX(';', #Email)-1)
This solution:
create function dbo.SplitString
(
#str nvarchar(max),
#separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
select
cast(1 as bigint),
cast(1 as bigint),
charindex(#separator, #str)
union all
select
p + 1,
b + 1,
charindex(#separator, #str, b + 1)
from tokens
where b > 0
)
select
p-1 ItemIndex,
substring(
#str,
a,
case when b > 0 then b-a ELSE LEN(#str) end)
AS Item
from tokens
);
GO
Taken from How do I split a string so I can access item x
In SQL Server 2016 you can use the built-in STRING_SPLIT function.
SELECT value FROM STRING_SPLIT(#var, ';')
Try using XML nodes to split and parse your string. Code sample below:
declare #Email as varchar(100), #del as varchar(10), #xml as xml;
set #Email='joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com';
set #del =';';
set #xml = '<root><c>' + replace(#Email,#del,'</c><c>') + '</c></root>';
select email.value('.','varchar(100)') as Email
from #xml.nodes('//root/c') as records(email);
Here this works I came across it quite sometime ago. Cannot take any credit for the work but this will work perfectly.
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
select *from dbo.fnSplitString('joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com',';')
I wrote this function that I use on a regular basis...
CREATE FUNCTION func_split(#value VARCHAR(8000), #delim CHAR)
RETURNS
#outtable TABLE (
i INTEGER,
value VARCHAR(1024)
)
AS
BEGIN
DECLARE #pos INTEGER
DECLARE #count INTEGER
IF LEN(#value) > 0
BEGIN
SET #count = 1
SET #value = #value + #delim
SET #pos = CHARINDEX(#delim, #value, 1)
WHILE #pos > 0
BEGIN
INSERT INTO #outtable (i, value) VALUES (#count, LEFT(#value, #pos - 1))
SET #value = RIGHT(#value, LEN(#value) - #pos)
SET #pos = CHARINDEX(#delim, #value, 1)
SET #count = #count + 1
END
END
RETURN
END
You when then call it with...
DECLARE #emails AS TABLE (
i INTEGER,
value VARCHAR(1024)
)
INSERT INTO #split SEELCT * FROM func_split('joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com', ';');
...and you end up with a temp table full of email addresses, i being their input order.
Your best bet is to turn the delimited string into columnar form and work from there.
You can use the iterative method, or the method using the Numbers table (which I prefer):
declare
#list varchar(1000),
#sep char(1)
set #list = 'joebloggs#gmailcom;jimbowen#aol.com;dannybaker#msn.com';
set #sep = ';'
-- iterative method
declare #res table (
c varchar(100)
)
declare
#pos_start int,
#pos_end int,
#len_sep int,
#exit int
select #pos_start = 1, #pos_end = 1, #len_sep = len(#sep), #exit = 0
while #exit = 0
begin
set #pos_end = charindex(#sep, #list, #pos_start)
if #pos_end <= 0 begin
set #pos_end = len(#list) + 1
set #exit = 1
end
insert #res(c) select substring(#list, #pos_start, #pos_end - #pos_start)
set #pos_start = #pos_end + #len_sep
end
select * from #res
-- the Numbers table method
select substring(#list, n, charindex(#sep, #list + #sep, n) - n)
from numbers
where substring(#sep + #list, n, 1) = #sep
and n < len(#list) + 1