I'm trying to implement a MySQL procedure (with if/else statements) inside a Granada query. The only issue is it won't let me create my procedure and call it from the same query...
ERROR
db query error: Error 1064: 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 tester(true)' at line 44
I'm confident the issue isn't with my syntax, but here's how the query looks:
CREATE PROCEDURE tester(
IN is_empty BOOLEAN
)
BEGIN
IF(is_empty) THEN
SELECT
...
from $dbName.table1
where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter)
union SELECT
...
from $dbName.table1
where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter)
ELSE
SELECT
...
from $dbName.table1
where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter);
END IF;
END;
CALL tester(true);
They seem to work on their own, but I have no idea why Grafana doesn't like this syntax. Any ideas?
NOTE:
Yes, it is necessary for me to create the procedure in Grafana query b/c I need to reference local Grafana variables (i.e. $KernelNameFilter, $gpuFilter, ...)
It's likely that you can't create procedure and call the procedure in a single call to the query interface. Most query interfaces do not support multi-query.
Even if the query interface supports multi-query, you can't use it to define a stored routine. Multi-query interfaces assume semicolon terminates the statement, so the first semicolon inside the body of your procedure would terminate the whole CREATE PROCEDURE statement. That's not what you want.
The MySQL client solves this by requiring you to change the statement terminator to something that doesn't appear in the body of the CREATE PROCEDURE statement. See https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html for details.
I need to reference local Grafana variables (i.e. $KernelNameFilter, $gpuFilter, ...)
You should make a procedure that takes your Grafana variables as parameters, and uses them in the queries within the procedure body — not create a brand new procedure each time you need to run the procedure.
Related
I have a Stored Procedure wrote in SQL Server that I need to convert to MySQL, which has this code inside.
SQL server code
declare #resultatSP table (...);
...
insert into #resultatSP execute other_procedure(...);
...
My problem is that in SQL Server, the "result" of the last select done in the SP other_procedure is stored in #resultatSP. (I don't know if it is conventional but it works), but I cannot reproduce it in MySQL.
I tried things like this:
MySQL code
drop temporary table if exists resultatSP;
create temporary table resultatSP (...);
...
resultatSP = CALL other_procedure(...);
OR
CALL other_procedure INSERT INTO resultatSP;
But nothing works.
I read that in MySQL, call stored procedure does not return result and we must use OUT/INOUT parameters. But I cannot change the other_procedure(...).
What is the most confusing is that this other_procedure has been convert in MySQL and it is used in java with some Javax.persistance annotations as #NamedNativeQuery or #SqlResultSetMapping and these annoations succeed to get the "result" of the last select of the stored procedure other_procedure(...) converted in MySQL. I don't know how these annotations make it.
I am trying to make a stored procedure in MYSQL(v5.7.21) with phpmyadmin(v4.7.9) that will sometimes return an empty result set.
CREATE DEFINER=`my_database`#`%` PROCEDURE `emptytest`(IN `_id` INT(11))
NOT DETERMINISTIC NO SQL SQL SECURITY DEFINER
select * from my_table where id=_id
and next call it with:
call emptytest(1);
this works fine when the id exists in the table:
id name
--------
1 bob
but throws an error when there are no rows to return:
call emptytest(11);
#2014 - Commands out of sync; you can't run this command now
However i would expect it to return the same as running the SQL statement:
select * from my_table where id=11
Which is an empty list:
id name
--------
I've been looking on StackOverflow for similar questions but most of them address issues with multiple queries which is not my case.
As far as I know MySQL documentation states that procedures should be able to return tables.
For the example I am showing the default options used by phpmyadmin, but i tried to tweak them to no avail.
What am I missing?
Nothing wrong with the procedure.
It is phpMyAdmin which does not handle stored procedures when executed using CALL in SQL tab.
You can run the procedure by clicking the icon in front of the procedure name in the left navigation tree.
Stored procedures tend to be 'fussier' about errors than simple statements (see below), so you need to put a handler in for that error.
DECLARE EXIT HANDLER FOR 2014 BEGIN select 'empty set' as `Error`; END;
The principle here is that you can't really handle these sort of errors in a simple query, so, from necessity, they are ignored; you can handle them in an SP, so, well, handle them...
I am trying to create a stored procedure in MySQL which is not supposed to be vulnerable to SQL injection. Hence I am using prepared statements inside this. I have a Patient table to which I want to add data using this procedure. This is what my stored procedure looks like.
DROP PROCEDURE IF EXISTS CreatePatient;
DELIMITER ##
CREATE PROCEDURE CreatePatient (IN alias VARCHAR(20))
BEGIN
PREPARE q1 FROM 'insert into Patient values (?)';
set #alias = alias;
EXECUTE q1 USING #alias;
END ##
DELIMITER ;
When I tried to run this without setting a new variable #alias,
EXECUTE q1 USING alias;
I am getting an SQL syntax error. From my understanding, it doesn't seem right to create a variable within the method body just to assign it the input variable to the procedure. What am I missing here?
Mysql has 3 types of variables
User Defined Variables
Local variables
session variables
User defined variables have session scope while local variables have a block scope i.e within BEGIN-END Block.
Because local variables are in scope only during stored program execution, references to them are not permitted in prepared statements created within a stored program. Prepared statement scope is the current session, not the stored program, so the statement could be executed after the program ends, at which point the variables would no longer be in scope. For example, SELECT ... INTO local_var cannot be used as a prepared statement. This restriction also applies to stored procedure and function parameters
See official docs
I'm running Workbench 5.2.47.
I have a long procedure I wrote with basic data checking. If a record did not exist in the database, the record would be inserted.
The procedure saved with no problems, but MySQL 5.5 throws an error when I try running it.
It is long, and has a lot of company sensitive data in it, or I would post it here.
I am trying to debug the procedure by executing small chunks of the code, but I can't seem to get Workbench to allow anything I try.
MySQL shows how to create a stored procedure in 5.1.5 Working with Stored Procedures.
Let me show you something very basic I am trying to write:
DELIMITER $$
DROP PROCEDURE IF EXISTS my_test;
CREATE PROCEDURE my_test()
BEGIN
SELECT * FROM Employees;
END $$
DELIMITER ;
With that, Workbench gives me the error, "syntax error, unexpected CREATE, expecting $end".
I don't understand that, but I need to get something done, so I am moving on.
I make a simpler query:
SET #Count=(SELECT Count(*) FROM tbl_object_users WHERE username='jp2code');
IF (#Count < 1) THEN
INSERT INTO tbl_object_users (username, date_time) VALUES ('jp2code', NOW());
END IF;
Again, I get an error, this time on my IF statement.
Next, I go into PhpMyAdmin to try running something from there using its database:
SET #Count=Count(id) FROM `tbl_object_users` WHERE `username`='jp2code';
It, too, tells me I have an error in my SQL syntax.
I did download and install the newest Workbench 6, but it did not solve the problem - and I did not like the interface, so I uninstalled it and went back to Workbench 5.2.
What is going on? SQL isn't that hard, so what is with these hurdles?
Problem with this:
DELIMITER $$
DROP PROCEDURE IF EXISTS my_test;
CREATE PROCEDURE my_test() ...
is that MySQL isn't seeing the semicolon at the end of the DROP PROCEDURE statement line as the end of the statement. This is because the preceding line told MySQL that the statement terminator was something other than a semicolon. You told MySQL that statements were going to be terminated with two dollar signs. So MySQL is reading the DROP PROCEDURE line, looking for the statement terminator. And the whole blob it reads is NOT a valid MySQL statement, it generates a syntax error.
The fix: either move the DROP PROCEDURE line before the DELIMITER $$ line; or terminate the DROP PROCEDURE statement with the specified delimiter rather than a semicolon.
The second problem you report is a syntax error. That's occurring because MySQL doesn't recognize IF as the beginning of a valid SQL statement.
The IF statement is valid only within the context of a MySQL stored program (for example, within a CREATE PROCEDURE statement.)
The fix: Use an IF statement only within the context of a MySQL stored program.
The third problem you report is also a syntax error. That's occurring because you don't have a valid syntax for a SET statement; MySQL syntax for SET statement to assign a value to user variable is:
SET #uservar = expr
MySQL is expecting an expression after the equals sign. MySQL is not expecting a SQL statement.
To assign a value to a user variable as the result from a SELECT statement, do the assignment within the SELECT statement, for example:
SELECT #Count := Count(id) FROM `tbl_object_users` WHERE `username`='jp2code'
Note that the assignment operator inside the SELECT statement is := (colon equals), not just =.
try this
DELIMITER $$
DROP PROCEDURE IF EXISTS my_test$$
CREATE PROCEDURE my_test()
BEGIN
SELECT * FROM `customer_to_pay`;
END $$
DELIMITER ;
I wrote a stored procedure (sp_archivev3) on MySQl Workbench which is as follows. Basically, Inserting values from one database to another.
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`MailMe`#`%` PROCEDURE `sp_archivev3`()
BEGIN
INSERT INTO
send.sgev3_archive(a_bi,
b_vc,
c_int,
d_int,
e_vc,
f_vc,
g_vc,
h_vc,
i_dt,
j_vc,
k_vc,
l_vc,
m_dt,
n_vch,
o_bit)
SELECT a_bi,
b_vc,
c_int,
d_int,
e_vc,
f_vc,
g_vc,
h_vc,
i_dt,
j_vc,
k_vc,
l_vc,
m_dt,
n_vch,
o_bit
FROM send.sgev3
WHERE m_dt BETWEEN '2014-06-09' AND CURDATE();
END
When I run call sp_archivev3(); , I get an error with an error code 1046: No database
selected SELECT the default DB to be used by double-clicking its name in the SCHEMAS list in the sidebar.
Please let me know what's wrong with my stored procedure.
The problem is that MySQL doesn't know which procedure named sp_archivev3 is supposed to be executed; MySQL doesn't know which database to look in. (Stored programs are objects in a specific database, just like tables are objects in a specific database.)
Either specify the current database with USE statement:
use mydatabase;
call sp_archivev3();
or qualify the procedure with the name of database:
call mydatabase.sp_archivev3();