Syntax issue writing conditional mySQL query in PHP - php

I have the following mySQL query written in the format of a PHP PDO script. I made sure to verify that all of the columns I refer to in the query exist.
So the issue seems to do with the syntax of the query itself. When executing the query in POSTMAN I see the issue seems to be where the if statement beings.
The following is the query:
$stmt = $conn->prepare('IF EXISTS (SELECT * `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']
]);

Alternative query:
$stmt = $conn->prepare("REPLACE INTO `Table` (`code`,`code_stat`) VALUES (:code,2)");
$stmt->execute(['code' => $_POST['code']);
If the row does not exists, it will be inserted otherwise it will be updated.
https://dev.mysql.com/doc/refman/5.7/en/replace.html

Think you're just missing the ‘FROM’.
SELECT * `Table1` WHERE
should be
SELECT * FROM `Table1` WHERE

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).

Search parameters SQLSRV_QUERY for WHERE IN syntax

I wonder if there is a way to pass some values into the parameters option on the sqlsrv_query function. I tried a few things but could not get it to work.
This query is what I want to be executed:
SELECT id, name, etc
FROM sqlTable
WHERE id IN ('1', '2', '100', '314')
I want to pass the WHERE IN values using the params option, like this:
$q = "SELECT id FROM sqlTable WHERE id IN ?";
$p = array(array('1', '2', '100', '314'));
sqlsrv_query($connection, $q, $p);
Right now I'm passing the values directly into the query string, but for obvious security reasons I want to pass them as parameters into the function.
Anyone any idea on how to achieve this?
Consider PDO binded parameters which you can pass a defined array in execute(). However, you would need to prepare the statement, knowing number of IN() clause items in advance.
try {
$dbh = new PDO("sqlsrv:server=$server;database=$database",$username,$password);
$sql = "SELECT * FROM sqlTable WHERE id IN (:first, :second, :third, :fourth)";
$STH = $dbh->prepare($sql);
$nums = array('1', '2', '100', '314');
$STH->execute($nums);
}
catch(PDOException $e) {
echo $e->getMessage()."\n";
}
So I have figured out this issue on the sql side. Now I pass a comma separated string with the ids to the query using the params in the sqlsrv_query() function. The query sets the string in a temporarily variable. Using a splitting function every id is stored in a temporarily table. As last I JOIN the temporarily table with the table from witch I want to get the results.
Splitting function in SQL:
CREATE FUNCTION dbo.splitstring ( #stringToSplit VARCHAR(MAX) )
RETURNS
#returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(',', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(',', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
PHP code and SQL query:
$q = "
DECLARE #inStr varchar(max)
SET #inStr = ?
DECLARE #tmpTable table (tmpID varchar(200))
INSERT #tmptable (tmpID)
SELECT * FROM dbo.splitstring(#inStr)
SELECT id, name, etc
FROM sqlTable
JOIN #tmpTable ON id = tmpID";
$p = array('1,2,100,314');
sqlsrv_query($connection, $q, $p);

UPDATE Query in Mysql Does not work

I have face a problem with my UPDATE Query in Mysql-
mysql_query( INSERT INTO `cost`
SET `cat_id` = '18', `feature_id` = '77', `type_id` = '5',
`cost_from` = '600', `cost_to` = '800'
WHERE `type_id` = 5 && `cat_id` = 18 && `feature_id` = 77");
type_id = 5 is not in my current table where i want to SET my new values.
The result is Unsuccessful.
I tried also an UPDATE query for the same
mysql_query( Update `cost`
SET `cat_id` = '18', `feature_id` = '77', `type_id` = '5',
`cost_from` = '600', `cost_to` = '800'
WHERE `type_id` = 5 && `cat_id` = 18 && `feature_id` = 77");
What should i do to insert and update values at the same time?
Note:
You don't use WHERE and SET on an INSERT query.
Make sure you have a table named cost along with the columns cat_id, feature_id, cost_from, cost_to, type_id.
You're trying to update the cost table columns with the ones you are looking for. Doesn't seem right.
Your first and second given sample codes have the same format, you just changed the first word, INSERT and UPDATE. Doesn't work that way.
You can, I think the recommendation of all people that would see your code, create better queries using mysql_* prepared statements.
A simple example of an INSERT query would look like this:
/* PREPARE YOUR QUERY */
$stmt = $con->prepare("INSERT INTO cost (cat_id, feature_id, type_id, cost_from, cost_to) VALUES (?,?,?,?,?)");
/* BIND PARAMETER TO THE QUERY. REPLACE NECESSARY VALUE OR VARIABLE */
$stmt->bind_param('iiiss', $catid,$featureid,$typeid,$costfrom,$costto);
$stmt->execute(); /* EXECUTE QUERY */
A simple example of an UPDATE query:
/* PREPARE YOUR QUERY */
$stmt = $con->prepare("UPDATE cost SET cat_id=?, feature_id=?, type_id=?, cost_from=?, cost_to=? WHERE id=?");
/* BIND PARAMETER TO THE QUERY. REPLACE NECESSARY VALUE OR VARIABLE */
$stmt->bind_param('iiissi', $catid,$featureid,$typeid,$costfrom,$costto,$id);
$stmt->execute(); /* EXECUTE QUERY */
First of all, you cannot use 'set ' with ' insert into' , and if you want to insert and update queries at the same time, then your best bet is using transaction . (you have to enclose insert and update queries in a transaction) , you cannot enclose both on a single sql statement..
This post might help you
SQL Update,Delete And Insert In Same Time

Update a single row in SQL

I am having trouble with a really simple SQL statement: UPDATE.
I would only like to update the booking_date column in a specific row.
Here is the statement I'm using:
UPDATE `coupon-codes` SET `booking_id`=:timestamp WHERE `id` = :id
I'm using PDO named placeholders.
I always get an incorrect syntax error. What am I doing wrong?
Edit:
I tried without backticks:
UPDATE coupon-codes SET booking_id = :timestamp WHERE id = :id
Still doesn't work.
Here's the error message I'm getting:
Edit 2:
Here is the error message I'm getting when using backticks:
Edit 3:
For reference, here is an INSERT statement I used before, which works without any problems:
INSERT INTO `coupon-codes` (`code`, `date`) VALUES (:code, :date)
Edit 4:
Sorry, wrongly said some things in the comments, to clarify, see this:
I am using BACKTICKS everywhere. This is the query that doesnt work:
UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id
I also had a typo in the original question which had booking_id instead of booking_date field, but that doesn't matter, since I'm getting a SYNTAX ERROR.
Here is the PHP code I'm trying to run it with:
$stmt = $db->prepare("UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id");
$stmt->bindParam(':timestamp', $time);
$stmt->bindParam(':id', $id);
$stmt->execute();
Basic MySQL syntax:
'foo' - single-quotes. turns the quote word into a string literal
`foo` - backticks. used to escape table/fieldnames that happen to be reserved words
SELECT 'select' FROM ... -- select the literal word "select" from some table
SELECT `select` FROM ... -- select the field NAMED "select" from some table
SELECT select FROM ... -- syntax error - using a reserved word "select"
Given your error messages, you probably have one of the following:
UPDATE 'coupon-code' ... -- can't update a string. must specify a table name
UPDATE coupon-code ... -- math operation: coupon MINUS code - not a table name
Have you tried to use Predefined Constants (http://php.net/manual/en/pdo.constants.php);
Example:
$stmt = $db->prepare("UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id");
$stmt->bindParam(':timestamp', $time, PDO::PARAM_STR);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();

Mysql - conditional insert query with select and PDO

I am unable to understand on how to apply insert query with select statement:
I have gone through this question also:
MySQL INSERT from a SELECT with PDO
But where is the VALUES part??
Like I have this query to insert in Mysql and here I use Values also:
$db_conn->beginTransaction();
$query = $db_conn->prepare('INSERT INTO mytable (name, user_id) VALUES(:sname, :uid)');
foreach($UploadData AS $DataValue)
{
$query->execute(array(':sname' => $DataValue['Name'],':uid' =>$_SESSION['uid']));
}
$db_conn->commit();
My motto is to check if the name exists with the same uid it shouldn't import the data otherwise it should. But Where are the values part :/ I am blind :P
EDIT1: From MySQL INSERT from a SELECT with PDO
How will this code block work if no VALUES is supplied?
$sql_enc = '
INSERT INTO sessionid (enc_id, enc_pass, enc_date)
(SELECT AES_ENCRYPT(username, :aeskey), AES_ENCRYPT(pwd, :aeskey), DATE_ADD(NOW(), INTERVAL 15 SECOND) FROM users WHERE username = :username)
';
$res_enc = $pdo->prepare($sql_enc);
$res_enc->bindParam(':aeskey', $aeskey);
$res_enc->bindParam(':username', $username);
$res_enc->bindParam(':pwd', $username);
$res_enc->execute();
$res_enc = null;
There are two valid INSERT syntax:
INSERT
INTO `table` [(field1, field2)]
VALUES ( 'val1', 'val2' )
Or
INSERT
INTO `table` [(field1, field2)]
SELECT 'val1', 'val2'
the selected columns are your value fields.
#comments:
Replace:
http://dev.mysql.com/doc/refman/5.5/en/replace.html
Procedures:
http://dev.mysql.com/doc/refman/5.6/en/create-procedure.html
You are defining the parameters :sname and :uid in your loop. The method execute takes the params and "put them" inside your query before executing this one.
On other words, the query is compiled when you call prepare() and the parameters are applied when you call execute().
Edit:
Ok I didn't understand.
The query includes a "SELECT" part which gives the values to insert. With SELECT you must not write "VALUES", as the documentation says:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]

Categories