I want to run the following mysql create function statement from PHP:
DELIMITER $$
CREATE FUNCTION `myFunc`(`instring` varchar(4000)) RETURNS int(11)
NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN
DECLARE position int;
....here comes function logic
RETURN position;
END$$
DELIMITER ;
But I get this mysql error:
check the manual that corresponds to your MySQL server version for the
right syntax to use near 'DELIMITER'
What can I do? Can I execute create statement without DELIMITER keyword?
You most likely do not need the DELIMTER command. That belongs to MySQL-centric client programs.
Please try with plain old semicolons:
if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
!$mysqli->query("CREATE PROCEDURE p(IN id_val INT) BEGIN INSERT INTO test(id) VALUES(id_val); END;")) {
echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
and let PHP worry about delimiting
CAVEAT
I got the above code from http://php.net/manual/en/mysqli.quickstart.stored-procedures.php
Related
I need to check if a column exists before trying to add it if not present.
Following information found in this post: mysql ALTER TABLE if column not exists
I added the following to my zen cart php file
$db->Execute("DROP PROCEDURE IF EXISTS `gdpr_accept`;
DELIMITER //
CREATE PROCEDURE `gdpr_accept`()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE " . TABLE_CUSTOMERS . " ADD `gdpr_accept` TINYINT(1) NOT NULL DEFAULT '0' AFTER `COWOA_account`;
END //
DELIMITER ;
CALL `gdpr_accept`();
DROP PROCEDURE `gdpr_accept`;");
However, I get the following error logged
[05-May-2018 19:37:02 Europe/Paris] PHP Fatal 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 'DELIMITER //
CREATE PROCEDURE gdpr_accept()
BEGIN
' at line 2 :: DROP PROCEDURE IF EXISTS gdpr_accept;
DELIMITER //
CREATE PROCEDURE gdpr_accept()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE customers ADD gdpr_accept TINYINT(1) NOT NULL DEFAULT '0' AFTER COWOA_account;
END //
DELIMITER ;
CALL gdpr_accept();
DROP PROCEDURE gdpr_accept; ==> (as called by) /Applications/MAMP/htdocs/gdpr/stOrm-PTO-fluSh/includes/init_includes/init_reconsent_popup_setup.php on line 72
However, when I run the same command in phpMyAdmin, after confirming that i want to "DROP PROCEDURE IF EXISTS gdpr_accept" it runs perfectly.
Note: If i attempt to split up the query, it will fail at
$db->Execute("DELIMITER //");
with this 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 'DELIMITER //' at line 1
Is there a reason why this SQL command can't be done via php, and is there a way round it?
DELIMITER is a builtin command in the mysql client, it is not a statement that the MySQL server recognizes. You can't run a DELIMITER statement using PHP.
But you don't need to use DELIMITER. That's only to help the mysql client tell where your CREATE PROCEDURE statement ends, because a procedure usually contains semicolon characters, and otherwise it would be ambiguous which semicolon was part of the procedure body versus the end of the procedure definition.
You should run one statement at a time from PHP. Then it's not ambiguous.
$db->Execute("DROP PROCEDURE IF EXISTS `gdpr_accept`");
$db->Execute("CREATE PROCEDURE `gdpr_accept`()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE " . TABLE_CUSTOMERS . " ADD `gdpr_accept` TINYINT(1) NOT NULL DEFAULT '0' AFTER `COWOA_account`;
END");
$db->Execute("CALL `gdpr_accept`()");
$db->Execute("DROP PROCEDURE `gdpr_accept`;");
By the way, there's no reason you need a procedure for this task, since you just drop the procedure when you're done anyway. It would be much simpler to just run the ALTER TABLE directly:
$db->Execute("ALTER TABLE " . TABLE_CUSTOMERS .
" ADD `gdpr_accept` TINYINT(1) NOT NULL DEFAULT '0' AFTER `COWOA_account`");
I see a lot of questions on Stack Overflow from people who seem to think it's a good idea to use stored procedures in MySQL. While stored procedures are common in Oracle and Microsoft SQL Server, they're more trouble than they're worth in MySQL. I avoid using stored procedures in MySQL.
I try to write a stored procedure like this but it does not work:
DROP PROCEDURE IF EXISTS `my_test`;
CREATE PROCEDURE `my_test`(
IN my_in_var VARCHAR(255),
OUT my_out_var VARCHAR(255)
)
BEGIN
IF(in_var == 'my_in_value') THEN
SET my_out_var = 'my_out_value1';
ELSE
SET my_out_var = 'my_out_value2';
END IF;
END
I try to execute from php with PDO
$conn = new PDO("mysql:host=".$mysql_host.";dbname=".$mysql_bd, $mysql_user, $mysql_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec($sql);
no errors but I can't see it on MySql server with
SHOW CREATE PROCEDURE my_test
So I tried to copy paste it in the SQL window of phpmyadmin and I got this syntax 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 '== 'my_in_value') THEN
SET my_out_var = 'my_out_value1'' at line 6
What is the correct syntax? And why PDO not show the error ?
Any help is welcome - thanks
Note, it has been pointed out to me that the below DELIMITER is not necessary in PHPMyAdmin which I don't use. So, DELIMITER is a client thing, such as needed by the likes of MySQL Workbench.
Stored Proc:
DROP PROCEDURE IF EXISTS `my_test`;
DELIMITER $$
CREATE PROCEDURE `my_test`(
IN my_in_var VARCHAR(255),
OUT my_out_var VARCHAR(255)
)
BEGIN
IF (my_in_var = 'my_in_value') THEN
SET my_out_var = 'my_out_value1';
ELSE
SET my_out_var = 'my_out_value2';
END IF;
END$$
DELIMITER ;
Test:
set #outme='';
call my_test('lizard',#outme);
select #outme;
-- my_out_value2
set #outme='';
call my_test('my_in_value',#outme);
select #outme;
-- my_out_value1
So you need to figure out what your intention is with the above.
You had a syntax error with the double =. And you were perhaps having a typo in the in_var that did not exist.
PHPMyAdmin (that does not require DELIMITER so I am told):
DROP PROCEDURE IF EXISTS `my_test`;
CREATE PROCEDURE `my_test`(
IN my_in_var VARCHAR(255),
OUT my_out_var VARCHAR(255)
)
BEGIN
IF (my_in_var = 'my_in_value') THEN
SET my_out_var = 'my_out_value1';
ELSE
SET my_out_var = 'my_out_value2';
END IF;
END
SQL Query -
CREATE TRIGGER `trigger_insert` AFTER INSERT ON `user`
FOR EACH ROW BEGIN
INSERT INTO `credentials` (`UserId`,`Password`,`UserType`,`Status`)
VALUES (NEW.UserId,NEW.Password,'2',NEW.Status);
END;
DELIMITER ;
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 '' at line 3
Need help... thanks in advance :)..
For your case you can use this statement -
CREATE TRIGGER `trigger_insert` AFTER INSERT ON `user`
FOR EACH ROW
INSERT INTO `credentials` (`UserId`,`Password`,`UserType`,`Status`) VALUES (NEW.UserId,NEW.Password,'2',NEW.Status);
What is the DELIMITER in MySQL and what it’s used for.
Delimiter problems I reckon:
DELIMITER $$
CREATE TRIGGER `trigger_insert` AFTER INSERT ON `user`
FOR EACH ROW BEGIN
INSERT INTO `credentials` (`UserId`,`Password`,`UserType`,`Status`) VALUES (NEW.UserId,NEW.Password,'2',NEW.Status);
END$$
DELIMITER ;
PHP mysqli quickguide for stored procedures, http://php.net/manual/en/mysqli.quickstart.stored-procedures.php :
if (!$mysqli->query("DROP PROCEDURE IF EXISTS p") ||
!$mysqli->query("CREATE PROCEDURE p(IN id_val INT) BEGIN INSERT INTO test(id) VALUES(id_val); END;")) {
echo "Stored procedure creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
does this not delete the procedure then replace it? is this the correct way to do it? what is the point in deleting it? does deleting it not negate the whole point of having a procedure which you can call for the duration of a MySQL connection?
You have to drop the 'old' procedure first, otherwise the CREATE will fail with an "already exists" errors. It's the same for pretty much EVERY object in a database, e.g.
CREATE TABLE foo ... // creates the table
CREATE TABLE foo ... // will **NOT** replace the one just created
you cannot 'overwrite' a table/proc/db just by redefining it. you have to drop the original one first.
Consider the chaos that'd occur if some poor DBA at a major bank accidentally ran
CREATE DATABASE clients;
and trashed their entire client db because the DB engine replaced the original DB with this new empty one.
I successfully use the below run_sql_script() function to execute SQL in a file using PHP.
static public function run_sql_script($script)
{
// Load and explode the sql file
$f = fopen($script,"r+");
$sqlFile = fread($f,filesize($script));
$sqlFile=preg_replace("/\\\;/", ';', $sqlFile); //replace semicolons with ascii
$sqlArray = explode(';',$sqlFile);
//Process the sql file by statements
foreach ($sqlArray as $stmt)
{
if (strlen($stmt)>8)
{
//Used to prevent blank lines at end of sql script from executing
$stmt=preg_replace("/;/", ';', $stmt); //replace ascii with semicolons
try {db::db()->exec($stmt);}
catch(PDOException $e){library::sql_error($e,$stmt);}
}
}
return;
}
I generate the SQL using MySQL Workbench, and recently, I added a trigger also through MySQL Workbench. It added the following SQL to the file.
DELIMITER $$
CREATE TRIGGER tg_contacts_upd AFTER UPDATE ON contacts
FOR EACH ROW
....
BEGIN
END$$
DELIMITER ;
Upon running the new file through my run_sql_script() function, I now get the following error.
Error in query: DELIMITER $$ CREATE TRIGGER tg_contacts_upd AFTER
UPDATE ON contacts FOR EACH ROW BEGIN END$$ DELIMITER SQLSTATE[42000]:
Syntax error or access violation: 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 'DELIMITER $$ CREATE TRIGGER
tg_contacts_upd AFTER UPDATE ON contacts FOR EACH ' at line 1
Any suggestion how to fix
Seems too easy, but the following appears to work.
static public function run_sql_script($script)
{
$sql = file_get_contents($script);
db::db()->exec($sql);
}