Using LOCATE string function in stored procedure - sql

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

Related

How to build dynamic query argument for external query?

I want to build dynamic query parameter based on declared variable for EXTERNAL_QUERY.
So I declare STRING variable via concatenation 2 strings:
DECLARE str STRING DEFAULT "SELECT * FROM public.stats WHERE import_date >= "||"'2021-11-29'";
Then trying to set this variable as argument into EXTERNAL_QUERY:
SELECT * FROM EXTERNAL_QUERY("dataset.location.conn_name", str);
It's returns an error:
Query error: Invalid table-valued function EXTERNAL_QUERY Connection argument in EXTERNAL_QUERY must be a literal string or query parameter
What I do wrong?
Not perfect, but works for me.
DECLARE str STRING DEFAULT '''"SELECT * FROM public.stats WHERE import_date >= "'''||"'2021-11-29'";
EXECUTE IMMEDIATE """
SELECT * FROM EXTERNAL_QUERY(\"dataset.location.conn_name\",?);
"""
USING str
Thanks #Timogavk for your answer, I spent a while looking for a solution.
Though in my case I had to change the DECLARE for something more like this, without the additional quotations for it to work (I was working on dynamically querying different tables):
DECLARE str STRING DEFAULT 'SELECT * FROM ' || <table_name> || ' Limit 10';

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

How to split a string using sybase query function

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

Sybase convert issue from float to varchar

First, I need to mention that my current sybase db version is Adaptive Server Enterprise 12.5.4. I aim to convert float data type into varchar via sybase convert function in order to concat several of these kinds of variables, format and store in string type.
Unfortunately, it is not the case. Simply using convert(varchar(20), float_var) or cast() function cannot correctly return the precise value.
For example, ...
declare #float_var float
begin
select #float_var =345.1237 --from table actually
select convert(varchar(20),#float_var) --return 345.1236999999
end
The incorrect string results returned occasionally have 99999 or 00001 suffix.
I tried many function including specify the precision, but there are still several cases not working on it. The sybase internal function does not exactly work on it.
I suppose this is a gerneral issue while using Sybase DB, however few answer found in serach. During my past experience, Sybase store procedure gammer always has sort of tolerance in runtime and internal fix when error encounter. This issue make me confused how Sybase works internally. Any advice would be appreciated, thanks in advance.
there are a couple of possible solutions for this.
firstly, let's try to convert the float to decimal first, then to varchar.
select cast(cast(#float_var as decimal(13,4)) as varchar)
alternatively, and this is where my ASE memory might fail me a little, would be to use the STR function like so:
Select ltrim(str(#float_var, 25, 5))
You have to TRIM the output as the STR function padding empty spaces on to the left of the result
this works for me:
declare #float_var float
begin
select #float_var = 96.332
select cast(cast(#float_var as decimal(13,4)) as varchar) -- Returns 96.3320
end
declare #float_var float
begin
select #float_var = 345.1237
select cast(cast(#float_var as decimal(13,4)) as varchar) -- Returns 345.1237
end

Writing the content of a local variable back to the resultset column?

Is it possible, by using a stored procedure, to fetch an integer column value from resultset into a local variable, manipulate it there and then write it back to the resultset's column?
If so what would the syntax look like?
Something along the following lines should do the trick.
DECLARE #iSomeDataItem INT
SELECT #iSomeDataItem = TableColumName
FROM TableName
WHERE ID = ?
--Do some work on the variable
SET #iSomeDataItem = #iSomeDataItem + 21 * 2
UPDATE TableName
SET TableColumName = #iSomeDataItem
WHERE ID = ?
The downside to an implementation of this sort is that it only operates on a specific record however this may be what you are looking to achieve.
What you are looking for is probably more along the lines of a user-defined function that can be used in SQL just like any other built in function.
Not sure how this works in DB2, but for Oracle it would be something like this:
Create or replace Function Decrement (pIn Integer)
return Integer
Is
Begin
return pIn - 1;
end;
You could use this in a SQL, e.g.
Select Decrement (43)
From Dual;
should return the "ultimate answer" (42).
Hope this helps.
Thanks for the replies, i went another way and solved the problem without using a procedure. The core problem was to calculate a Date using various column values, the column values ahd to to converted to right format. Solved it by using large "case - when" statements in the select.
Thanks again... :-)
Why not just do the manipulation within the update statement? You don't need to load it into a variable, manipulate it, and then save it.
update TableName
SET TableColumnName=TableColumnName + 42 /* or what ever manipulation you want */
WHERE ID = ?
also,
#iSomeDataItem + 21 * 2
is the same as:
#iSomeDataItem + 42
The function idea is an unnecessary extra step, unless most of the following are true:
1) you will need to use this calculation in many places
2) the calculation is complex
3) the calculation can change