MySQL basic trigger - not working - php

I'm trying to create following trigger:
CREATE TRIGGER clean
AFTER INSERT ON `mecze_druzyny`
begin
DELETE * FROM bramki;
END;
DELIMITER ;
Which should be ran just after following:
$sql2 = "INSERT INTO mecze_druzyny (id_druzyny, id_meczu, gospodarz) VALUES (
:team2,
:lastmatch,
:gospodarz)";
$stmt = $db->prepare($sql2);
$stmt->bindParam(':team2', $id2, PDO::PARAM_INT);
$stmt->bindParam(':lastmatch', $last_match, PDO::PARAM_INT);
$stmt->bindParam(':gospodarz', $a=0, PDO::PARAM_STR);
$stmt->execute();
Unfortunately I'm getting an 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 'begin
DELETE * FROM bramki' at line 3

It's an error with your delete syntax.
Get rid of the * so you're left with
DELETE FROM bramki
A typical delete will be in the format
DELETE FROM TableName WHERE ... -- the WHERE clause is optional here

Add Delimiters to make it correct. Here is the correct syntax to do so:
DELIMITER //
CREATE TRIGGER clean
AFTER INSERT
ON mecze_druzyny FOR EACH ROW
BEGIN
DELETE FROM bramki;
END; //
DELIMITER ;

Related

Syntax error in SELECT query inside PHP script

I am trying to create a query inside a PDO script that checks if a record exists if it does the query should update the record and if it doesn't exist it should create a new one.
The column that should only exist once in the table is not an INDEX key (cannot make it unique right now) so it is not set as unique and I cannot use the ON DUPLICATE KEY UPDATE
I would like to use this queries logic below to make it work:
$stmt = $conn->prepare('IF EXISTS (SELECT * FROM `Table1` WHERE `code`= :code )
UPDATE `Table1`
SET `code_stat` = 2
WHERE code = :code
ELSE
INSERT INTO `Table1` (`code`,`code_stat`)
VALUES (:code, 2 ) ' );
$stmt->execute([
'code' => $_POST['code']
]);
The problem is when executing the query I get the following error saying there is a syntax problem:
SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near
'IF EXISTS (SELECT * FROM Table1 WHERE code= ? ) UPDATE Table1' at line 1
If you can't add a unique key to the table, you can attempt an update first, and if that doesn't update any rows, do an insert. Something like this:
$stmt = $conn->prepare('UPDATE `Table1` SET `code_stat` = 2 WHERE code = :code');
$stmt->execute(array(':code' => $_POST['code']));
if (!$stmt->rowCount()) {
// no rows updated, so insert
$stmt = $conn->prepare('INSERT INTO `Table1` (`code_stat`, `code`) VALUES (2, :code)');
$stmt->execute(array(':code' => $_POST['code']));
}
Note that you may need to set the PDO::MYSQL_ATTR_FOUND_ROWS attribute to ensure that the UPDATE query returns 1 if it finds the row but the value doesn't change. You must set that attribute when you make the connection e.g.
$conn = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_FOUND_ROWS => true));
Why not write a stored procedure to handle this, similar to the below:
DROP PROCEDURE IF EXISTS db.SP_NEW_CODE;
CREATE PROCEDURE db.`SP_NEW_CODE`(IN `in_code` INT)
BEGIN
DECLARE numFound INT DEFAULT 0;
SET numFound=(SELECT * FROM `Table1` WHERE `code`= in_code);
IF (numFound=0) THEN
INSERT INTO `Table1` (`code`,`code_stat`) VALUES (in_code, 2 );
ELSE
UPDATE `Table1` SET `code_stat` = 2 WHERE code = in_code
END IF;
END;
From your code, simple execute CALL SP_NEWCODE(3); (for example, where 3 is the appropriate code value).

Problem calling parameterized MariaDB SP with LIMIT using PHP

I have been stumped with this and cannot find a working example or tutorial anywhere.
Given the following stored procedure:
SQL
delimiter $$
CREATE PROCECURE sp1(IN 'myoffset' INT, IN 'myrows'
INT)
begin
select * from t1
limit 'myoffset', 'myrows'
END$$
delimiter
I am trying to call it from PHP like so:
... establish $conn, then
PHP
// ver1:
$sql = ( "SET #p0 = $tmp1;" . " SET #p1 = $tmp2;" . "
CALL `sp1`(#p0, #p1);" );
//OR
//ver2
$sql = "SET #p0 = `$tmp1`; SET #p1 = `$tmp2`; CALL
`sp1`(#p0, #p1);";
$result = mysqli_query($conn, $sql);
Neither one works. MariaDB complains that
"Error description: 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 'SET #p1 = 25; CALL sp1(#p0, #p1)' at line 2"
Any help would be much appreciated!
What is in $tmp1?
If it is a number, then the first one should work, but the second one does not make sense because it becomes
SET #p0 = `1234`;
I assume there is not a column or table named 1234? Keep in mind that backtics are for columns, tables, and database names.
If $tmp is the string "a string", then you get
SET #p0 = a string; -- strings need to be quoted here
or
SET #p0 = `a string`; -- again that is treated as a column (etc) name.
After that, you have another problem: Do not tack multiple statements together (separated by ;); run them separately.
Finally, there is no need for #p0, etc:
$sql = "CALL `sp1`('$tmp1', '$tmp2')";
is sufficient.
Well, not quite. If the values for $tmps came from the outside world, see the dreaded "SQL Injection" problem.
Oh, and what if
$tmp1 = "Don't do this";
Then you get
$sql = "CALL `sp1`('Don't do this', '$tmp2')";
Look at the single quotes. There are 3 of them. How will this be parsed?

MySQLi prepared statement not taking valid query that calls a procedure

$prepared = $db->prepare("
SET #content = ?;
CALL add_interest_if_not_exists( #content );
SET #iid = (SELECT interests_id
FROM interests
WHERE content = #content);
REPLACE INTO profile_interests (user_id, interests_id, likes)
VALUES (
?,
#iid,
?
)
");
echo $db->error;
The error 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 'CALL add_interest_if_not_exists( #content ); SET #iid = (SELECT i' at line 3
The query works using MySQL workbench (hard-coded values). Why won't it in my prepared statement...
This is not a single query but a set of queries.
Therefore you have to run them one by one, each with separate query() or prepare()/execute() call.
Why not use a stored procedure?
CREATE PROCEDURE add_user_interest(p_content varchar(200), p_user_id int,p_likes int)
BEGIN
CALL add_interest_if_not_exists( p_content );
SET #iid = (SELECT interests_id
FROM interests
WHERE content = p_content);
REPLACE INTO profile_interests (user_id, interests_id, likes)
VALUES (
p_user_id,
#iid,
p_likes
);
END
End you will call as single prepared statement
$prepared = $db->prepare("CALL add_user_interest( ?, ? , ? )");

MYSQL Error #1064 - Update multiple rows

I have to update a dynamic form where the user can add, deleted and update questions in a questionnaire. I've created all my code that will generate one query which is executed once at the end.
I get a problem when I try to update more than one question at the same time (INSERT and DELETE works like a charm).
$query = ''; // append every thing to update in this variable
// for each questions check if needs to be modify, if yes append.
$query .= 'UPDATE `questionnaire` SET `id_category` = '.$categoryValue.' WHERE `id` = '.$idQuestion.'; '
Example of an output
UPDATE `questionnaire` SET `id_category` = 1 WHERE `id` = 1; UPDATE `questionnaire` SET `id_category` = 3 WHERE `id` = 2;
Submit to the database;
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->close();
}
If I only have one UPDATE, it works like a charm. As soon that I have 2 updates, I get this MYSQL error :
errno : 1064
error : 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 'UPDATE `questionnaire` SET `id_category` = 3 WHERE `id` = 2' at line 1
Does anyone have an idea why it only happens when I have two UPDATE ? If yes, how should I fix this.
As suggested by Mike W (Thank you), I changed
if ($stmt = $mysqli->prepare($query)) {
$stmt->execute();
$stmt->close();
}
for
if ($mysqli->multi_query($query)) {
// Success
}

Displaying stored procedure query while calling procedure

I created a stored procedure like this and called that procedure with input arguments. I want to get the procedure it self while calling it with arguments just like echo query in normal case.
$procedure = "CREATE PROCEDURE pdruser_login(IN userName VARCHAR(300), IN password VARCHAR(500))
BEGIN
DECLARE _sqlQuery VARCHAR(2046);
SET _sqlQuery = 'SELECT login_id, authorized, admin_authorize FROM tbluser_login WHERE user_name = userName AND user_pwd = password AND authorized = 1 AND privacy_policy = 1 AND is_deleted = 0';
SET #sqlQuery = _sqlQuery;
PREPARE dynquery FROM #sqlQuery;
EXECUTE dynquery;
DEALLOCATE PREPARE dynquery;
END;";
if (!mysqli_query($this->con,"DROP PROCEDURE IF EXISTS pdruser_login") ||!mysqli_query($this->con,$procedure))
{
file_put_contents("minefile1.txt", "Stored procedure creation failed: (" . mysqli_errno($this->con) . ") " . mysqli_error($this->con));
}
if (!($result = mysqli_query($this->con,"CALL pdruser_login('".$userName."','".$password."'")))
{
file_put_contents("minefile2.txt","CALL failed: (" . mysqli_errno($this->con) . ") " . mysqli_error($this->con));
}
But the above procedure shows an error "CALL failed: (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 1".
How can I display the stored procedure query while calling the stored procedure.Is there is any way for getting the dynamic query so it will be easy to trace the errors in complex queries?
For some reason you don't store your SQL in a variable - so, you cannot have it in your debug info
$sql = "DROP PROCEDURE IF EXISTS pdruser_login";
mysqli_query($this->con,$sql) or trigger_error(mysqli_error($this->con)." [$sql]");
$sql = $procedure;
mysqli_query($this->con,$sql) or trigger_error(mysqli_error($this->con)." [$sql]");
// and so on.
note that trigger_error is a way more useful that file_put_contents. it can put the error in a log file but also it can display it on-screen which id very handy. And it have indispensable file/line stamp
First for creating a MySQL procedure you need to set DELIMITER other than ; then reset delimiter after procedure execution as Inside priocedure all bock should treat as single query but query inside procedure can break sql statement (due to using ;)
Example from mysql site.
DELIMITER //
DROP PROCEDURE IF EXISTS GetAllProducts //
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END //
DELIMITER ;

Categories