Stored functions in MySQL not working (invalid use of groupby) - mysql

Hi all I started learning functions in MySQL and I am trying different things. I created this function below, that should return the count of different departments/titles
however I am getting an error on the group by part when I call the select statement
DELIMITER //
CREATE function num_of_titles(titles_ varchar(80)) returns char deterministic
return count(titles_);
// DELIMITER ;
select title, num_of_titles(title) as count_title from titles
group by 1;
enter image description here

The
return count(titles_);
is not valid SQL. COUNT-function cannot be used alone, only as part of a proper SQL query.

Related

MySQL - Stored Function SET SELECT INTO returning Error 1366 in VIEW

Note - I have edited to better reflect the complexity on the math. Sorry, very new to this.
I am trying to repeatedly run a mathematical function on certain metrics in a dataset in MySQL. The mathematical lag function involves several variables but I only need to alter one of them. The idea is to create this as a function and then call the function in a view. I am able to create the function and the view. However, when I call the view I receive
Error Code: 1366. Incorrect decimal value: 'Variable' for column ``.``.`metric` at row 280
Normally this would just indicate bad data entry from the original table. But here's the catch - the table only has 279 observations. Why is my function trying to interpret nonexistent rows?
I've tried pulling out just the select function and it works fine so it's not a problem there.
Here is the code I've used with some dummy names to preserve data integrity. The actual formula is more complicated but the same error occurs with even basic math so I've used that.
To create the function
DELIMITER //
DROP FUNCTION IF EXISTS Levels;
CREATE FUNCTION Levels(
metric decimal(65,4),
dataset VARCHAR(60)
)
RETURNS DECIMAL(65,4)
BEGIN
DECLARE levels DECIMAL(65,4);
SET levels = NULL;
SELECT
metric - (LAG(metric,1) OVER (PARTITION BY clown_id ORDER BY year));
INTO levels
FROM dataset;
RETURN levels;
END //
To create and call view
DROP VIEW IF EXISTS Circus_Mainfile;
CREATE VIEW Circus_Mainfile AS
SELECT
my_database.circus_inputs.*,Levels('Clowns', 'my_database.circus_inputs`) AS More_clowns
FROM my_database.circus_inputs;
SELECT * FROM Circus_Mainfile LIMIT 279;
Thanks in advance.
The function shouldn't select from the table, that's done by the view itself. The function should just receive the value that was selected, and perform the calculation.
CREATE FUNCTION Levels(prev_level DECIMAL(65, 4)) RETURNS DECIMAL(65, 4)
BEGIN
RETURN prev_level + 2
END
Then you call it in the view like this:
CREATE VIEW Circus_Mainfile AS
SELECT i.*,
Levels(i.clowns) AS More_clowns
FROM my_database.circus_inputs AS i;

Throw error for multiple results in PostgreSQL SQL function

Consider the following example function:
CREATE FUNCTION test()
RETURNS INTEGER
LANGUAGE SQL
AS $$ SELECT * FROM UNNEST(ARRAY[1,2,3,4,5]); $$
;
When we execute it like so:
SELECT test();
the result we get back is 1. In other words, the function just returned the first element of the result set.
I have a convenience function that retrieves an ID based on data in the rest of the row. It lets callers query on data that is often unique to a particular row but is not strictly unique. Primarily, it will be used to populate some mostly static data. Allowing the call to use the row data instead of hard coding the ID makes it more readable and easier to maintain when new data does come along. This depends on the caller having some familiarity with the data, but that's a reasonable assumption to make for the usage at hand.
The problem is if the user makes a mistake and gives arguments that are insufficient to filter the query's results to one row, I want my function to error out instead of returning the first result. How can I accomplish this? Do I have any options other than to switch my language to PL/PGSQL and check it manually?
(Using PostgreSQL 9.3).
You could put the entire query as a subquery in the SELECT list. When attempting to return more than one row, this will fail with this error:
ERROR: more than one row returned by a subquery used as an expression
Based on your example, this one would fail:
CREATE FUNCTION test()
RETURNS INTEGER
LANGUAGE SQL
AS $$ SELECT (SELECT * FROM UNNEST(ARRAY[1,2,3,4,5])); $$
and this one wouldn't fail:
CREATE FUNCTION test()
RETURNS INTEGER
LANGUAGE SQL
AS $$ SELECT (SELECT * FROM UNNEST(ARRAY[1])); $$

Mysql function to return row count from a procedure call [duplicate]

This question already has answers here:
How can I get the number of rows 'returned' from a result set of a stored procedure
(2 answers)
Closed 7 years ago.
I am trying to write a function to return the number of rows a call to a stored procedure would return. I'm trying to minimise repetition of the code (for reduced code maintenance/debugging- the procedure select is long).
The stored procedure just read-only selects rows matching certain criteria (vague I know but details should not be material to the question).
I could just copy the procedure into a function and change the select to count() but as it is long with multiple joins I was hoping to write a function that could call the procedure and return the row count. The goal is not for optimised running but for efficient code maintenance, boiler plate reduction.
I have tried this as a test:
DELIMITER //
CREATE PROCEDURE IF NOT EXISTS proc_select1()
BEGIN
SELECT 1;
END //
CREATE FUNCTION IF NOT EXISTS select1_count() RETURNS INT UNSIGNED
BEGIN
CALL proc_select1();
RETURN FOUND_ROWS();
END //
DELIMITER ;
However when I SELECT select1_count(); - which I am hoping will return 1 - I get the "cannot return a result set from a function" error.
I tried assigning FOUND_ROWS to a variable, clearing the result set then returning the variable value but can't get it to work.
Does anyone know a work around or do I really need to copy-paste the procedure and convert to a SELECT COUNT and function?
I'm using MySQL 5.5.16 (can upgrade if necessary), Windows 7 (nobody seems to want to upgrade :) with HeidiSQLv7.0.0.4053 (if relevant)
As always, any help much appreciated.
first use distinct to get distinct values then use count on that..like
select count(distinct column_name) from table_name
cannot return a result set from a function
This error happens when a SELECT query is done in a procedure without storing the output values.
Other thing : don't forget to use SQL_CALC_FOUND_ROWS to indicates your DBMS to store the number of found rows.
I tried to make it work without any temporary variable (Maybe there is exists a mysql keyword to not "return" the set of the SELECT query), but no success. Here a piece of code which works using temporary var.
CREATE PROCEDURE proc_select1()
BEGIN
DECLARE temp INT;
SELECT SQL_CALC_FOUND_ROWS 1 INTO temp;
END //
CREATE FUNCTION select1_count() RETURNS INT UNSIGNED
BEGIN
CALL proc_select1();
RETURN FOUND_ROWS();
END //
The result is 1 as expected :-) cf : SQLFiddle
It appears this is not possible. The select statement is required to SELECT INTO something to avoid the cannot return a result set from a function error during the function call. If this is not possible or required in the SELECT statement used in the procedure then the function will not run without error.
Using CLEAR QUERY CACHE or FLUSH QUERY CACHE after the procedure call did not help (and is probably a bad idea / bad coding anyway).

How to fetch result of stored procedure in iReport?

I am using Ubuntu 12.04,iReport-4.7,MySQL,mysql-jdbc driver
I write stored procedure in MySQL
DELIMITER //
CREATE PROCEDURE first()
BEGIN
select * from person where id in (11,22,33);
END //
DELIMITER;
which return id & name as fields
& calling it from iReport
select id+1,name from (call first)
gives me syntax error,
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'call first)' at line 1
but when I run call first in query executor,no error
How should I get required field for further calculations ?
Does this is possible in MS-SQL ?
It is not possible.
You might consider to use temp table.
Please check this SO Post: MySql: Can a stored procedure/function return a table?
Regards

Return array in stored function

I am trying to use the result of a stored function in a WHERE statement in MySQL (5.x), but it fails because in the function I am selecting values from a table into an INT variable and then returning them/it, which obviously doesn't work if the SELECT returns more than 1 row. I've tried returning a TABLE (as I understood TABLE means array in MySQL) but that didn't work either.
Is there any way that I could do something like:
SELECT ID FROM myTable WHERE ID IN my_function(params);
Thank you.
This cannot be done...
First, you cannot use a stored function to return multiple results - you would need to use a stored procedure.
The MySQL docs state:
Statements that return a result set can be used within a stored procedure but not within a stored function.
Second, you cannot use a stored procedure in a query - see this SO question.
Have you considered using 'HAVING ...' at the end of your query?