I have a stored procedure in MySQL that takes a single parameter that can consist of 1 or more values. I want to be able to filter by these values, so I created a function that can take a string and a delimiter parameter
my_func('val1,val2,val3',',')
and it returns a string
'val1','val2','val3'
. I am then calling this function in the where clause such as
WHERE x IN (my_func('val1,val2,val3',','))
But this is not working. It does not give any error, but it keeps running without ever returning anything. I have tested the function individually and it works fine and returns in less than a second. The query I am trying to run it in is a test query that is very basic. Replacing the function with a regular string such as
WHERE x IN ('val1','val2','val3')
works perfectly fine and returns in just a couple seconds. Is what I am trying to do even possible? Thanks!
IN requires the argument to be a literal list, it doesn't re-parse the string. Use FIND_IN_SET:
WHERE FIND_IN_SET(x, 'val1,val2,val3'))
Related
Is there any known issue about using variables in CONCAT or am I making a mistake in below query?
set #m := '2016';
select concat('2015','-',#m);
Expected result is 2015-2016, but strangely it returns
2015F201
I tested many other variations with and without using variables, it works as expected without variables, but return similiar 'unexpected' results when used with variables.
I'm using DBeaver as SQL client, it somehow thinks that the result of that query is binary:
select concat('2015','-',#m);
and show it incorrectly: 2015F201 (not exactly hexadecimal)
When I change settings under Preferences window, Common / Result Sets / Binaries / Binary Data formatter to String, it shows correctly.
I have a string returned from a function "'aa','bb','cc',..."(the function uses GROUP_CONCAT). I want to use this as a condition in the IN clase of mysql.
SELECT name,class,comment
FROM vwstudent v
WHERE name IN (select func())
I want the query to act like
SELECT name,class,comment
FROM vwstudent v
WHERE name IN ('aa','bb','cc','dd',..)
I assume ('aa','bb','cc','dd',..) is acting as a whole string here and isn't generating any result. What can I do to run this query error less.
I'm not sure if it'll help. But you might be able to hack something together by using PREPARE and EXECUTE as described here: How To have Dynamic SQL in MySQL Stored Procedure
... but that's completely new to me. I've never used anything like that in MySQL.
SELECT s.* FROM (SELECT setUserId('abcd123') p) tmp_p, main_article_view s
The problem is that the function setUserId(userId char(36)) in MySQL set a session variable, that is being used in main_article_view; the first time I run this query, it does not work, because the function gets executed in the end.
But when I run it second time, it does works perfectly; because was set previously on first run in session.
The limitation for me is that I cannot use the simple := operator to set the userIdParam (session variable) in NHibernate; because NHibernate uses : for named parameters.
The below query works, but it is not working as I said with NHibernate.
SELECT s.* FROM (SELECT #userIdParam:='abc123' p) tmp_param, main_article_view s
The workaround I am doing right-now is calling first the function setUserId() and then calling the actual query alone like select * from main_article_view, which works, but then there will be two calls, which I don't like.
Actually I just want to use View with parameter; so any suggestions would be welcomed?
Thanks & Regards
UPDATE: I've answered this myself below.
I'm trying to fix a performance issue in a MySQL query. What I think I'm seeing, is that assigning the result of a function to a variable, and then running a SELECT with a compare against that variable is relatively slow.
If for testings sake however, I replace the compare to the variable with a compare to the string literal equivalent of what I know that function will return (for a given scenario), then the query runs much faster.
For example:
...
SET #metaphone_val := double_metaphone(p_parameter)); -- double metaphone is user defined
SELECT
SQL_CALC_FOUND_ROWS
t.col1,
t.col2,
...
FROM table t
WHERE
t.pre_set_metaphone_string = #metaphone_val -- OPTION A
t.pre_set_metaphone_string = 'PRN' -- OPTION B (Literal function return value for a given name)
If I use the line in option A, the query is slow.
If I use the line in option B, then the query is fast as you would expect any simple string compare to be.
Why?
Was finished writing the question when the answer hit me, so posting anyway for knowledge sharing!
I realised that the return value of the metaphone function was UTF8.
The compare to a latin1 field was obviously incurring a fairly heavy performance overhead.
I replaced the variable assignment with:
SET #metaphone_val:= CONVERT(double_metaphone(p_parameter) USING latin1);
Now the query runs as fast as I would expect.
Background
Creating a wrapper function for a SQL statement.
Problem
A function returns 1 row, whereas the query upon which the function is based returns 100+ rows. The parameter values are identical:
SELECT * FROM as_rpt.tasc_fsa( 'ABC', '2010-01-01'::date, '2011-01-01'::date );
The tasc_fsa function is a SELECT statement with a few table joins; the function language is 'sql' rather than 'plpgsql'.
Question
What reasons would a function return a single row yet the exact same query that the function uses, when not called via the function, correctly returns over 100 rows?
Any ideas would be most helpful.
Thank you!
Have you use RETURN SETOF ...?
SETOF indicates you want to return more than 1 row.
I'm pretty sure you forgot to use 'RETURN SETOF'.
You mention the function "joins a few tables". Your example obviously doesn't. If there are joins being performed, it is possible this is causing less results.
The way the dates are being interpreted is another possibility. When you get 1 answer, is it within the range you specify?