How to split a string using sybase query function - sql

String str = 'ce765e1bc7:abc879:53:7011:2'
How to split the string using sybase query function to value 7011
I have working stored proc for this. But wanted to know if sybase provides any inbuilt function to do so.

If you know the position of the first character and length of the required pattern, you can use 'substring'
Syntax - substring(expression, start, length)
select substring('ce765e1bc7:abc879:53:7011:2',22,4)
If you only have string and the pattern to find but not sure about the length, you can additionally use 'charindex' and 'char_length' as shown in the example below:
BEGIN
DECLARE #stpos INT, #stlen INT
SELECT #stpos = charindex('7011', 'ce765e1bc7:abc879:53:7011:2')
SELECT #stlen = char_length('7011')
SELECT substring('ce765e1bc7:abc879:53:7011:2',#stpos, #stlen)
END

Related

SQL Server: Return a string in a specific format

In TSQL, I need to format a string in a predefined format.
For eg:
SNO
STRING
FORMAT
OUTPUT
1
A5233GFCOP
*XXXXX-XXXXX
*A5233-GFCOP
2
K92374
/X-000XXXXX
/K-00092374
3
H91543987
XXXXXXXXX
H91543987
I am trying with FORMATMESSAGE() built in function.
For ex:
FORMATMESSAGE('*%s-%s','A5233','GFCOP')
FORMATMESSAGE('/%s-000%s','K','92374')
FORMATMESSAGE('%s','H91543987')
I am able to get the first argument by replace function but issue is second/third/fourth/.. arguments.
I don't know how to count respective X's between the various delimiters, so that I can use substring to pass in second/third/.. arguments. If I can count the respective # of X's from the Format column, I feel using substring we can get it but not sure how to count the respective X's.
Please let me know how to get through it or if there is any other simple approach.
Appreciate your help.
Thanks!
It's in theory quite simple, could probably be done set-based using string_split however that's not ideal as the ordering is not guaranteed. As the strings are fairly short then a scalar function should suffice. I don't think it can use function in-lining.
The logic is very simple, create a counter for each string, loop 1 character at a time and pull a character from one or the other into the output depending on if the format string is an X or not.
create or alter function dbo.fnFormatString(#string varchar(20), #format varchar(20))
returns varchar(20)
as
begin
declare #scount int=1, #fcount int=1, #slen int=len(#string), #flen int=Len(#format), #output varchar(20)=''
while #scount<=#slen or #fcount<=#slen
begin
if Substring(#format,#fcount,1)='X'
begin
set #output+=Substring(#string,#scount,1)
select #scount+=1, #fcount +=1
end
else
begin
set #output+=Substring(#format,#fcount,1)
set #fcount +=1
end
end
return #output
end;
select *, dbo.fnFormatString(string, [format])
from t
See working Fiddle

Can I convert centigrade to farenheit in a query (not a function)

In Oracle I can convert centigrade to farenheit in an SQL query, see below. It seems SQL Server does not have full regex functionality. Is it possible to do this without dropping into a function, which I currently do?
(UNISTR('00B0') is the degree symbol we use)
The requirement is for any string that contains [digits]°C to be converted to same string with [new_digits]°F.
SELECT replace(replace(v_text_f,replace(regexp_substr(v_text_f,'\-? [[:digit:]]+\.?[[:digit:]]*'||UNISTR('\00B0')||'C'),UNISTR('\00B0')||'C'),
replace(regexp_substr(v_text_f,'\-?[[:digit:]]+\.?[[:digit:]]*'||UNISTR('\00B0')||'C'),UNISTR('\00B0')||'C')*9/5+32||UNISTR('\00B0')||'F'),
UNISTR('\00B0')||'F'||UNISTR('\00B0')||'C',UNISTR('\00B0') ||'F')
FROM (SELECT '38'||UNISTR('\00B0')||'C' as v_text_f FROM DUAL)
Try this, comparing to Oracle code, extremely simplified version:
DECLARE #C nvarchar(10) = '38'+CHAR(0x00B0)+'C' --38°C
SELECT CONVERT(nvarchar(10),CONVERT(int ,LEFT(#C, CHARINDEX(CHAR(0x00B0), #C)-1))*9/5+32)+CHAR(0x00B0)+'F'
--100°F

MS Access using VBA in a SQL IN clause

I'm trying to pass some values from a vba function to an SQL.
This is my SQL
SELECT *
FROM Hierarchy3
WHERE ID IN (getList("1 and 2"));
this is the definition of the vba function:
Function getList(Measure As String) As String
when I call the function I get: 1,2,3 as a String.
if I run the SQL as
SELECT *
FROM Hierarchy3
WHERE ID IN (1,2,3);
it works fine, but combining the two doesn't work. So I guess the String type is wrong, can you please help?
Your problem is that your query does not work like you expect it. Your function returns a string, so the query performed is:
SELECT *
FROM Hierarchy3
WHERE ID IN ("1,2,3");
Notice the quotation marks. Basically you are comparing an integer to a string and so doesn't return any results.
What you can do is use the INSTR function to see if the ID can be found in the string:
SELECT *
FROM Hierarchy3
WHERE INSTR(getList("1 and 2"),ID);
Now it will work because ID 1 can be found in the string "1,2,3" so the INSTR function will return the position where it can be found.

Is there a more efficient way to handle these replace calls

I'm querying across two dbs separated by a legacy application. When the app encounters characters like, 'ü', '’', 'ó' they are replaced by a '?'.
So to match messages, I've been using a bunch of 'replace' calls like so:
(replace(replace(replace(replace(replace(replace(lower(substring([Content],1,153)) , '’', '?'),'ü','?'),'ó','?'), 'é','?'),'á','?'), 'ñ','?'))
Over a couple thousand records, this can (as you expect) is very slow. There is probably a better way to do this. Thanks for telling me what it is.
One thing you can do is implement a RegEx Replace function as a SQL assembly and call is as a user-defined function on your column instead of the Replace() calls. Could be faster. You also want to probably to the same RegEx Replace on your passed in query values.
TSQL Regular Expression
You could create a persisted computed column on the same table where the [Content] column is.
Alternatively, you can probably speed up the replace by creating a user defined function in C# using a StringBuilder. And you can even combine both of these solutions.
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlString LegacyReplace(SqlString value)
{
if(value.IsNull) return value;
string s = value.Value;
int l = Math.Min(s.Length, 153);
var sb = new StringBuilder(s, 0, l, l);
sb.Replace('’', '?');
sb.Replace('ü', '?');
// etc...
return new SqlString(sb.ToString());
}
Why not first do the same replace (chars to "?") on the string you are searching for in the app side using regular expressions? E.g. your SQL server query that was passed a raw string to search for and used these nested replace() calls will instead be passed a search string already containing "?"s by your app code.
Could you convert the strings to varbinary before comparing? Something like the below:
declare
#Test varbinary (100)
,#Test2 varbinary (100)
select
#Test = convert(varbinary(100),'abcu')
,#Test2 = convert(varbinary(100),'abcü')
select
case
when #Test <> #Test2 then 'NO MATCH'
else 'MATCH'
end

Using LOCATE string function in stored procedure

Is anyone familiar with using the LOCATE with a passed in string varialbe? I am trying to use it to determine if there is a comma in a string that was set in the stored procedure but have not been able to get it to work properly. My code looks something like this
DECLARE string VARCHAR(10);
DECLARE comma_found INT;
SET string = 'hello, world';
SET comma_found = SELECT LOCATE(',',string);
IF( comma_found <> 0 ) THEN
...execute code....
END IF;
This code will not complie because of the SELECT LOCATE and I can not figure out what is wrong. Is it my syntax? Usage? Is there any other string maniuplation function I can use to accomplish this? I am doing this within a stored procedure in Mysql.
I haven't used MySQL in a long time so I'm not completely familiar with the newer syntax but from some googling, I believe
SET comma_found = SELECT LOCATE(',',string);
should be
SELECT #comma_found := LOCATE(',',string);
then you can use #comma_found eg:
SELECT #comma_found
It seems that you're trying to assign a data set to the variable rather than the result of the LOCATE
See here: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html
Well the syntax for LOCATE is LOCATE(substring, string). Your query literally says LOCATE(',', string) where string is a varchar(10). Your string is actually more than 10 characters long though =P