create function throws error in mysql,can someone help me out? - mysql

I am just trying to create a function which means to check if a table,function or view exists in a mysql database. But I get some errors in my database. Can someone help me out?
DELIMITER $$
DROP FUNCTION IF EXISTS check_if_exists$$
CREATE FUNCTION check_if_exists
(
object_name VARCHAR(100),
db_name VARCHAR(100),
object_type ENUM('t', 'f', 'v', 'p')
)
RETURNS INT
BEGIN
IF (object_type='t') THEN
SELECT COUNT(1) INTO #f_result
from information_schema.TABLES as t1
where t1.TABLE_SCHEMA=db_name
and t1.TABLE_NAME=object_name;
ELSE IF (object_type='f') THEN
select count(1) INTO #f_result
FROM information_schema.ROUTINES as info
WHERE info.ROUTINE_SCHEMA = db_name
AND info.ROUTINE_TYPE = 'FUNCTION' AND info.ROUTINE_NAME = object_name;
ELSE IF (object_type='v') THEN
select count(1) into #f_result
from information_schema.VIEWS as t1
where t1.TABLE_SCHEMA=db_name and t1.TABLE_NAME=object_name;
ELSE IF (object_type='p') THEN
SELECT COUNT(1) INTO #f_result
FROM information_schema.ROUTINES as info
WHERE info.ROUTINE_SCHEMA = db_name
AND info.ROUTINE_TYPE = 'PROCEDURE'
AND info.ROUTINE_NAME = object_name;
END IF;
return (#f_result);
END$$
delimiter ;
another thing, the info of mysql:
mysql Ver 14.14 Distrib 5.5.37, for Linux (x86_64) using readline 5.1
and the error message is:
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 '' at line 31
as you see, the error message is not helpful. This definition of function do not depend any user database. So you can try in your own DBMS.

You start four IF statements, but you only have one END IF at the end.
The error message about syntax error near '' indicates that it parsed to the end of the statement, expected to find more syntax (like the balancing END IF for the remaining nested IF statements), and didn't find it. The syntax error tries to give you context by showing you what text exists in the remaining part of the statement after the error, but if it reaches the end before it discovers the error, then there is no following text to report.
You might consider using the CASE statement instead:
DELIMITER $$
DROP FUNCTION IF EXISTS check_if_exists$$
CREATE FUNCTION check_if_exists (
object_name VARCHAR(100),
db_name VARCHAR(100),
object_type ENUM('t', 'f', 'v', 'p')
)
RETURNS INT
READS SQL DATA
BEGIN
DECLARE f_result INT DEFAULT 0;
CASE object_type
WHEN 't' THEN
SELECT COUNT(1) INTO f_result
FROM information_schema.TABLES AS t1
WHERE t1.TABLE_SCHEMA = db_name
AND t1.TABLE_NAME = object_name;
WHEN 'f' THEN
SELECT COUNT(1) INTO f_result
FROM information_schema.ROUTINES AS info
WHERE info.ROUTINE_SCHEMA = db_name
AND info.ROUTINE_TYPE = 'FUNCTION'
AND info.ROUTINE_NAME = object_name;
WHEN 'v' THEN
SELECT COUNT(1) INTO f_result
FROM information_schema.VIEWS AS t1
WHERE t1.TABLE_SCHEMA = db_name
AND t1.TABLE_NAME = object_name;
WHEN 'p' THEN
SELECT COUNT(1) INTO f_result
FROM information_schema.ROUTINES as info
WHERE info.ROUTINE_SCHEMA = db_name
AND info.ROUTINE_TYPE = 'PROCEDURE'
AND info.ROUTINE_NAME = object_name;
END CASE;
RETURN (f_result);
END$$
DELIMITER ;
Re your comment:
I am trying to use if...else if...else like any other language. There is no else if in mysql?
Not in the way you were using. There is no "ladder" possible with an indefinite number of else-if clauses in standard SQL.
But many languages allow the else block to contain another if/then/else statement. So you can make complex branching code. But you have to terminate each if/then/else statement properly.
IF ... THEN /* start 1st statement */
ELSE
IF ... THEN /* start 2nd statement */
ELSE
IF ... THEN /* start 3rd statement */
ELSE
END IF /* end 3rd statement */
END IF /* end 2nd statement */
END IF /* end 1st statement */
Languages that permit ladders:
Perl (elsif)
Ruby (elsif)
PHP (elseif)
Python (elif)
BASIC (elseif)
PL/SQL (elsif)
PL/pgSQL (elsif)
F# (elif)
Languages that do not permit ladders, but do permit nested control structures:
C
C++
C#
Objective-C
Java
Javascript
ANSI SQL, Transact-SQL
Pascal, Delphi
Awk
Scala
Haskell
R
Swift
Dart
Go

Related

Flyway | MariaDb - Unable to execute conditional block

I want to add a not null column to a table with existing data. My toolset includes MariaDb and flyway. Here's what I am doing
IF NOT EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'MY_DATA_TABLE'
AND table_schema = '${schemaName}'
AND column_name = 'NewColumnName'
) THEN
ALTER TABLE MY_DATA_TABLE ADD COLUMN 'NewColumnName' INT;
SELECT ID INTO #val FROM MASTER_TABLE WHERE lower(Name) = 'XYZ';
UPDATE MY_DATA_TABLE SET NewColumnName = #val;
ALTER TABLE MY_DATA_TABLE MODIFY COLUMN 'NewColumnName' INT NOT NULL;
END IF;
Doing mvn flyway:migrate gives me this error
[ERROR] SQL State : 42000
[ERROR] Error Code : 1064
[ERROR] Message : You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''NewColumnName'
INT' at line 7
I even tried placing some running select statement inside, but the error remains the same. Please suggest some workaround. Please also recommend if there's another way to achieve the objective.
Thanks!
I suspect the issue is with quoting the column name. Try executing the SQL interactively and see if you get the same error. Then try and get it working successfully. In a related question the answer was to try no quotes around column names or to escape them with back ticks.
Here's how I ended up to meet the desired.
DROP PROCEDURE IF EXISTS `proc_UpdateMyColumn`;
DELIMITER //
CREATE PROCEDURE `proc_UpdateMyColumn`
(
)
BEGIN
DECLARE valueToSet INT;
IF NOT EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'MY_DATA_TABLE'
AND table_schema = '${schemaName}'
AND column_name = 'NewColumnName'
) THEN
ALTER TABLE MY_DATA_TABLE ADD COLUMN NewColumnName INT;
SELECT ID INTO valueToSet FROM MASTER_TABLE WHERE lower(Name) = 'XYZ';
UPDATE MY_DATA_TABLE SET NewColumnName = valueToSet;
ALTER TABLE MY_DATA_TABLE MODIFY COLUMN NewColumnName INT NOT NULL;
END IF;
END;
DELIMITER;
CALL `proc_UpdateMyColumn`();
DELIMITER;

MySQL - CREATE DEFINER syntax error

I am trying to update a stored function in our MySQL database. The update is to be released to multiple devices so I am doing it through an update.sql file.
Here is the function
DROP FUNCTION `STAFF_MPT`;
CREATE DEFINER=`jelena`#`%` FUNCTION `STAFF_MPT`(`par_stocktake_staff_id` INT) RETURNS DECIMAL(20,0) NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER BEGIN
DECLARE proc_total INT;
DECLARE proc_time INT;
SET proc_total = (SELECT SUM(quantity) FROM stocktake_scans WHERE stocktake_staff_id = par_stocktake_staff_id);
SET proc_time = (SELECT TIMESTAMPDIFF( SECOND , MIN( scan_date ) , MAX( scan_date ) ) AS area_time
FROM stocktake_scans
WHERE stocktake_staff_id = par_stocktake_staff_id
);
RETURN (proc_total/proc_time)*3600;
END
It was just reported to me by the test team that the report that uses this function did not generate properly. I tried to run the code in PMA SQL query window and got the following:
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 '' at line 3
Can someone tell me what am I missing? According to this, line 3 is empty, so how could it possibly have a syntax error?
As of MySQL docs:
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. By default, mysql itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause mysql to pass the entire stored program definition to the server.
To redefine the mysql delimiter, use the delimiter command.
#juergen_d hinted in the comment: you have to define your procedure with a delimiter:
DROP FUNCTION `STAFF_MPT`;
delimiter ||
CREATE DEFINER=`jelena`#`%` FUNCTION `STAFF_MPT`(`par_stocktake_staff_id` INT) RETURNS DECIMAL(20,0) NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER BEGIN
DECLARE proc_total INT;
DECLARE proc_time INT;
SET proc_total = (SELECT SUM(quantity) FROM stocktake_scans WHERE stocktake_staff_id = par_stocktake_staff_id);
SET proc_time = (SELECT TIMESTAMPDIFF( SECOND , MIN( scan_date ) , MAX( scan_date ) ) AS area_time
FROM stocktake_scans
WHERE stocktake_staff_id = par_stocktake_staff_id
);
RETURN (proc_total/proc_time)*3600;
END
||
delimiter ;

stored procedure is issuing syntax error

I am trying to create a mysql stored procedure with phpmyadmin:
CREATE PROCEDURE AddTableColumn()
BEGIN
IF (SELECT COUNT (table_name)
FROM information_schema.tables
WHERE table_name IN ('authors', 'publishers') = 2 )
print 'specified tables exist...';
ELSE
print 'specified tables unavailable...';
END IF;
END​
above code is a snippet that should search information schema
for the availability of authors and publishers tables,
then proceed to add new column in each table if present.
the print statement was for debug purpose. when i clicked the
GO command, here's the error message :
MySQL said:
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 'print 'avail...'; ELSE print 'unavail...'; END IF; END' at line
7.
what am i doing wrong ? i have even tried other code as a test,
all failing with the same error. code as simple as:
BEGIN
IF (6 > 4)
print 'greater';
ELSE
print 'lesser';
END IF;
END ​
all failed. any help will be appreciated.
'print' is not recognized in MySQL.
If you want to read back the output, just use a select in the SP.
Change part of your SP as below:
DECLARE found_status VARCHAR(255) DEFAULT NULL;
IF ....
SELECT 'specified tables exist...' INTO found_status;
ELSE
SELECT 'specified tables unavailable...' INTO found_status;
END IF;
SELECT found_status;

parameters sql query inside of a stored procedure mysql

I'm working with stored procedures in mysql, so I have the following procedure:
DELIMITER ##
DROP PROCEDURE IF EXISTS generarEstadisticoRD ##
CREATE PROCEDURE generarEstadisticoRD ( mesInicial INT,anualInicial INT, mesFinal INT,anualFinal INT, codigoEntidad CHAR(3),mes INT )
BEGIN
DECLARE controlador INT;
DECLARE tipoDocumento CHAR(2);
DECLARE cursorDocumentos CURSOR FOR SELECT DISTINCT e.claseDocIdentidadFallecido
FROM EstadisticoRD e WHERE e.anual>=anualInicial AND e.anual<=anualFinal
AND e.mes >=mesInicial AND e.mes<=mesFinal AND e.codOficina=codigoEntidad;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET controlador = 1;
DROP TEMPORARY TABLE IF EXISTS estadistico;
CREATE TEMPORARY TABLE IF NOT EXISTS
estadistico( TIPO CHAR(2), MES INT );
OPEN cursorDocumentos;
cursorLoop : LOOP
FETCH cursorDocumentos INTO tipoDocumento;
IF( controlador=1 ) THEN
LEAVE cursorLoop;
END IF
/**
*Lógica
*/
INSERT INTO estadistico(`TIPO`,`MES`)
SELECT DISTINCT
c.descripcion,
IFNULL( (SELECT e.numRegistrosReportados FROM estadisticoRD e WHERE e.codOficina=codigoEntidad
AND e.claseDocIdentidadFallecido=tipoDocumento AND e.mes=mes ), 0)
FROM estadisticoRD e, claseDoc c WHERE e.codOficina=codigoEntidad AND e.claseDocIdentidadFallecido=tipoDocumento
AND c.claseDoc = e.claseDocIdentidadFallecido;
END LOOP cursorLoop;
CLOSE cursorDocumentos;
SELECT * FROM estadistico;
END ##
DELIMITER ;
I get the following messages when I try to execute the procedure:
Executed successfully in 0,001 s, 0 rows affected.
Line 2, column 1
Error code 1064, SQL state 42000: 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 'INSERT INTO estadistico(`TIPO`,`MES`)
SELECT DISTINCT c.descripcion,
' at line 24
Line 3, column 1
So, what am I doing wrong?.
UPDATE 1:
The I corrected the mistake with semicolon thanks #Daniel Victoria
But now I get the following mistake:
Error code 1267, SQL state HY000: Illegal mix of collations (latin1_spanish_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='
Exactly I get this mistake when I do
SELECT DISTINCT e.claseDocIdentidadFallecido
FROM EstadisticoRD e WHERE ... AND e.codOficina=codigoEntidad;
why when I do e.codOficina=codigoEntidad I get this mistake, how to fixed it?.
UPDATE 2:
To solve it, I need to put COLLATE latin1_swedish_ci after to the column that has the mistake.
In this case the new query is :
SELECT DISTINCT *
FROM estadisticoRD e WHERE e.anual>=anualInicial AND e.anual<=anualFinal
AND e.mes >=mesInicial AND e.mes<=mesFinal AND e.codOficina = codigoEntidad COLLATE latin1_swedish_ci;
I hope to finish this procedure the best way.
Your are missing a semicolon (;) after the "END IF"

mySQL If statement

I am trying to make this If Statement work, but I can't seem to make it do what I want. If I do a select #result, It'll give me the value 0, then why doesn't the IF statement work?
SET #message = '((sometihng here))';
select LEFT(#message, 1) into #firstChar;
select STRCMP(#firstChar,'(') into #result;
IF (#result = 0) THEN
SET #message = 'true';
//more selects and cals here;
END IF;
select #message;
I should get true, but I don't it shows me an error:
SQL query: IF( #result =0 ) THEN SET #message = 'true';
MySQL said:
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 'IF (#result = 0) THEN SET #message = 'true'' at line 1
try use function http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if
SELECT IF(#result = 0, 'true', '((something here))') AS message
As Max Mara pointed out, that's a good work aroud. The reason the IF wasn't working is not because the syntax is incorrect, but because flow control functions like IF ... THEN are only valid inside of stored procedures or functions, All this thanks to #TehShrike
The IF .. THEN .. ELSE syntax in MySQL is only available for procedural code (stored precudures, functions, triggers..), but not for SELECT statements.
IF ELSE USED IN STORED PROCEDURE EXAMPLE BELOW
DELIMITER //
CREATE PROCEDURE NAME(IN Number INT)
BEGIN
IF roll= 1
THEN SELECT * FROM table1 WHERE id = roll;
ELSE
SELECT * FROM table2 WHERE id = 2;
END IF;
END //
DELIMITER ;