UPDATE Query in Mysql Does not work - php

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

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

Only Insert if unique(check 2 rows)

I am learning SQL and I am in situation where I have to INSERT values into database only if it do not exist already.
My tableview structure is like this:
+----------+-----------+-----+-----+
| first_id | second_id | timestamp |
+----------+-----------+-----------+
I Want to insert only if there is not same first_id and second_id e.g if in table there is first_id 1 and second_id 2 and I am adding it again, I do not want to add it anymore. So if the first_id and second_id rows already have values 1 and 2 then do not add but if first_id is 3 and second_id is 1 then I would allow the inserting.
This is my query ATM:
INSERT INTO `testtable`.`ids` (`first_id`, `second_id`) VALUES (:first_id, :second_id)
And like this I tried with NOT EXISTS but it is not working:
NOT EXISTS (SELECT first_id, second_id FROM `testtable`.`ids` WHERE first_id = : first_id AND second_id = : second_id) INSERT INTO `testtable`.`ids` (`first_id `, `second_id `) VALUES (: first_id, : second_id)
The last mentioned query gives me Syntax error but once I even got the integrity violation and it told me to check documentation.
I am executing my queries using PHP ->query(""); function.
I tried to do like IF NOT EXISTS and NOT EXISTS but those didn't work. How should I approach to this?
This is simple. Declare first_id and second_id as composite key. I would prefer not to make any changes in your PHP Code but make your DB structure versatile so that it doesn't accept any duplicate values how-so-ever you are inserting it.
CREATE TABLE `demo` (
`first_id` smallint(6) DEFAULT NULL,
`second_id` smallint(6) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `first_id` (`first_id`,`second_id`)
)
Now first_id and second_id will never accept duplicate values.
^ table contains values (1,2). Now inserting (1,3).
^the table accepts (1,3). Now inserting (1,2) again.
the insert statement throws an error. Now the table will never accept duplicate values for the key (first_id,second_id).
If the table already exists and you're not creating it from scratch, simply execute:
alter table `table_name` add unique key (first_id, second_id);
This will prevent the duplicate values henceforth.
You may try this if you are using PHP and MySql:
<?php
//Added database connection code here
$first_id = $_POST['first_id '];
$second_id = $_POST['second_id '];
$sql = "select * from ids where first_id = ".$first_id ." and second_id ='".$second_id."'" ;
$result = $mysqli->query($sql);
$row = $result->fetch_row();
if($row[0]) {
$mysqli->close();
} else {
//preapare an insert statement
$stmt = $mysqli->prepare(" INSERT INTO `ids` (first_id, second_id) VALUES (?,?)");
$stmt->bind_param("ii", $first_id, $second_id);
//execute the statement
if( $stmt->execute() ) {
unset($first_id);
unset($second_id);
} else {
echo $mysqli->error;
}
//close statement
$stmt->close();
$mysqli->close();
}
?>
Checking for existence for the first and second ids and additionally declare 2 sql variables for first and second ids and set them as per required.
DECLARE #Exists int; #first_id int; #second_id int;
SET #first_id = 1;
SET #second_id = 2;
SELECT #Exists = COUNT(*) FROM [testtable] where [first_id] = #first_id and [second_id] = #second_id;
Condition to insert if count of matched records is 0:
IF(#Exists = 0)
BEGIN
INSERT INTO [testtable](first_id, second_id)
VALUES(#first_id,#second_id)
END

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

Ordering Mechanism in Mysql

I have a matter in PHP & Mysql Project.
Simply, I have two tables project and project features,
Every project has as specific features.
CREATE TABLE projects (
ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name varchar(255) NOT NULL
);
CREATE TABLE projects_features (
projectId INT NOT NULL,
name varchar(255) NOT NULL,
value varchar(255) NOT NULL,
weight INT NOT NULL
);
INSERT INTO projects VALUES (NULL,'project1');
INSERT INTO projects VALUES (NULL,'project2');
INSERT INTO projects_features VALUES (1,'Feature1','Feature1 Value',1);
INSERT INTO projects_features VALUES (2,'Feature2','Feature2 Value',2);
INSERT INTO projects_features VALUES (1,'Feature3','Feature3 Value',3);
INSERT INTO projects_features VALUES (2,'Feature4','Feature4 Value',4);
INSERT INTO projects_features VALUES (1,'Feature5','Feature5 Value',5);
I Get the Project features by:
SELECT * FROM projects_features WHERE projectId = 1 ORDER BY weight ASC;
So the bigger weight will be down and lower weight will be Up.
Now,
In My View I have move up and move down buttons, so I can re-sort project features.
I can firstly select the current item weight then select the upper item weight ,
then type two update queries to exchange the weight between the two rows,
but it's not a professional way , I don't like to use four queries.
I need to do it in one query Instead of four queries.
Can anybody help please ?
Here's how I'd tackle this, assuming I've understood the question.
First, I'd add a featureId column to projects_features, and make (projectId, featureId) the composite primary key. This isn't actually necessary to my solution; it just makes the rest a whole lot easier. For the next part you need to be able to reference individual records in projects_features.
Next, I'd have the Move buttons populate an array in PHP, like
$update_list = array();
$update_list[i] = array(':project_id' => $proj_id,
':feature_id' => $feat_id,
':new_weight' => $weight);
Finally, I'd do the update through a PHP function that encapsulates the UPDATE statements, like this:
function updateWeights($update_array, $dbh)
{
$sql = 'UPDATE project_features
SET weight = :new_weight
WHERE projectId = :project_id
AND featureId = :feature_id'
$stmt = $dbh->prepare($sql);
foreach ($update_array as $update_item)
{
$stmt->execute($update_item);
}
}
Note I'm using PDO here; it could also be done with mysqli, although mysqli doesn't support named bind parameters so the syntax would be slightly different, something like
function updateWeights($update_array, $dbh)
{
$sql = 'UPDATE project_features
SET weight = ?
WHERE projectId = ?
AND featureId = ?'
$stmt = $dbh->prepare($sql);
foreach ($update_array as $update_item)
{
$stmt->bind_param('i', $update_item[':new_weight']);
$stmt->bind_param('i', $update_item[':project_id']);
$stmt->bind_param('i', $update_item[':feature_id']);
$stmt->execute();
}
}
Also note that I haven't actually run this code, and so make no representation that it is free of syntax or other errors.
I hope that helps.

(PDO PHP) The fastest way to update or insert multiple rows?

I don't know how to update or insert multiple rows by using PDO. Please help me.
Something that is in my mind is:
$stmt = $dbh->query("update_line_1; update_line_2; update_line_3");
//update_line_1: update table a set a.column1 = "s1" where a.id = 1
//update_line_2: update table a set a.column1 = "s2" where a.id = 2
//....
$stm = $dbh->query("insert_line_1; insert_line_3; insert_line_3");
//something is like the update line above.
I don't know this way works or not. And If you have another way, please let me know. Thank you so so much.
And if I use prepare statement, I just update each row each time. (This is much more safe than above)
$stmt = $dbh->prepare("update table a set a.colum1 = :column1 where a.id = :id");
$stmt->bindParam(":column1","s1");
$stmt->bindparam(":id",1);
$stmt->execute();
The most hate thing I don't want to do is using a loop goes through all elements in an array, and update or insert each element each time
Is another way to mass safely update or insert multiple rows to database? thank for your help.
Sorry about my English.
For inserts, you can insert multiple rows worth of data with the following syntax:
INSERT INTO table (col1, col2, col3)
VALUES
('1', '2', '3'),
('a', 'b', 'c'),
('foo', 'bar', 'baz')
For updates, the update will by default effect as many rows as meet the criteria of the query. So something like this would update an entire table
UPDATE table SET col = 'a'
If you are trying to update different values for each row, you don't really have much of a choice other than to do a query for each operation. I would suggest however that, building on your PDO example, you could do something like this:
$update_array = array(
1 => 'foo',
2 => 'bar',
10 => 'baz'
); // key is row id, value is value to be updated
$stmt = $dbh->prepare("UPDATE table SET column1 = :column1 where id = :id");
$stmt->bindParam(":column1",$column_value);
$stmt->bindparam(":id",$id);
foreach($update_array as $k => $v) {
$id = $k
$column_value = $v;
$stmt->execute();
// add error handling here
}
With this approach you are at least leveraging the use of the prepared statement to minimize query overhead.

Categories