I have a little problem with MySQL query. I'm using PDO queries, which now just insert values into the tables (see below):
$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
$stmt -> execute();
tmp table structure is the following:
CREATE TABLE IF NOT EXISTS `tmp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`test_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`question_id` int(11) NOT NULL,
`answer_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
)
I want to insert answer_id value if it's wasn't there and check if user_id at the same time, otherwise just update, example:
I have two users with user_id=1 and user_id=2, they're answering the questions and every answer for each student stores separately. User_id=1 picked answer_id = 3 and user_id=2 picked the answer_id = 3. However, then one user realised this was a wrong answer and wants to change it to another one (suppose answer_id=2), I want the query update the current answer_id=3 WHERE user_id=1 to answer_id=2
You can make an INSERT IGNORE for the same, which looks simpler and will be atomic with some issues.
Step are like
Create a unique index on (user_id,question_id, answer_id)
ALTER TABLE tmp add index user_qn_ans_idx (user_id,question_id, answer_id);
Now just do the insert, and probably on duplicate key update as well
INSERT INTO tmp (user_id,question_id, answer_id) values
(, , )
ON DUPLICATE KEY UPDATE answer_id = VALUES(answer_id)
Add a select count and do conditionals below:
$stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id and answer_id = :answer_id");
$stmt->bindValue( 'user_id', 1 );
$stmt->bindValue( 'question_id', 1 );
$stmt->bindValue( 'answer', 1 );
$stmt->execute();
$oExists = $stmt ->fetch();
if( !empty( $oExists ) )
{
// Run update sql...
}
else
{
// Run insert sql...
$stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id AND answer_id = :answer_id");
$stmt->bindValue( 'user_id', 1 );
$stmt->bindValue( 'question_id', 1 );
$stmt->bindValue( 'answer_id', 1 );
$stmt->execute();
$oExists = $stmt ->fetch();
if( !empty( $oExists ) ) {
echo "update";
$stmt = $dbh->prepare("UPDATE tmp SET answer_id = :answer_id WHERE user_id = {$_SESSION['UserID']} AND question_id = {$_POST['question']}"); //updates the counter each time test created
$stmt -> bindParam(':answer_id', $_POST['select_answer'], PDO::PARAM_INT);
$stmt -> execute();
} else {
echo "insert";
$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
$stmt -> execute();
}
Here is always updates, but not inserts..
Related
I am new to statements, so please come slowly on me. I have checked questions asked by others but didnt see a solution to solve my issue.
I am trying to create a userpage with prepared statements so they can add products to their stores.
I would like to get store_id from stores and insert into produtcs on an insert product form.
I have tried several methods but they didnt work.
Here are my attempts:
Connection
$mysqli = new mysqli(host, dbase, username, password);
First method prepare statements: I have tried this method without bind_result too.
if ($stmt = $mysqli->prepare("INSERT INTO products (user_id, cat_id, store_id, item_name, item_code, item_description, item_qtty, item_price, item_seo_url, item_image, item_date) SELECT store_id FROM stores WHERE user_id = ?")) {
$stmt->bind_param("i", $user_id);
$user_id = filterString($_SESSION['id']);
$stmt->execute();
$stmt->bind_result($store_id);
if($stmt->fetch()){
echo " Records created successfully. Redirect to landing page";
header("location: index.php");
exit();
} else{
echo "Something went wrong. Please try again later.";
}
}
$stmt->close();
Second method sql prepare statements: I have tried this too but didnt work:
$sql = "INSERT INTO products (user_id, cat_id, store_id, item_name, item_code, item_description, item_qtty, item_price, item_seo_url, item_image, item_date) SELECT ?, store_id FROM stores WHERE user_id = ?";
if($stmt = $mysqli->prepare($sql)){
$stmt->bind_param("iiisiisiisss", $user_id, $cat_id, $store_id, $item_name, $item_code, $item_description, $item_qtty, $item_price, $item_seo_url, $item_image, $item_date);
$user_id = $_SESSION['id'];
$cat_id = $cat_id;
$store_id = $store_id;
$item_name = $item_name;
$item_code = $item_code;
$item_description = $item_description;
$item_qtty = $item_qtty;
$item_price = $item_price;
$store_seo_url = seo_url($item_name);
$item_image = $vtyol;
$item_date = $date;
if($stmt->execute()){
echo " Records created successfully. Redirect to landing page";
header("location: index.php");
exit();
} else{
echo "Something went wrong. Please try again later.";
}
}
$stmt->close();
Didnt have a chance to get store_id from stores, I echo store ID in page to see if I get it, its empty.
how can I make it work ?
Do I need to declare all values in bind_param in first method ? (I tried and didnt work).
if so, how to add clause $stmt->bind_param("i", $user_id);.
I really dont know what else to try, need your advice and helps.
Gtg to hospital now be back in 1 hour, will answer your questions and answers.
Thank you all
Last example I tried with the code from #Michael Eugene Yuen it keep saying something went wrong, because of cant get $store_id from stores table.
My codes were to long so I shortened them and tried getting same result.
Here is last example not wroking:
$sql = "INSERT INTO products (
user_id, store_id, name, salary
)
SELECT ?, ?, ?, ?,
`store_id` FROM stores WHERE user_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("iisii", $user_id, $store_id, $name, $salary, $user_id);
$user_id = $user_id;
$store_id = $store_id;
$name = $name;
$salary = $salary;
if($stmt->execute()){
header("location: index.php");
exit();
} else{
echo "Something went wrong. Please try again later.";
}
$stmt->close();
Database struckter for both tables:
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(100) NOT NULL,
`store_id` varchar(100) NOT NULL,
`name` varchar(255) NOT NULL,
`salary` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `stores` (
`store_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(100) NOT NULL,
`name` varchar(255) NOT NULL,
`salary` int(10) NOT NULL,
PRIMARY KEY (`store_id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `stores` (`store_id`, `user_id`, `name`, `salary`) VALUES
(1, '12', 'aaaaaaaaaaad', 12),
(2, '12', 'sada', 1234656);
Your were trying to insert data into 11 columns but only 1 value was passed into your statements
Your statement should look like this:
$sql = "INSERT INTO products (
user_id, cat_id, item_name, item_code, item_description,
item_qtty, item_price, item_seo_url, item_image, item_date,
store_id
)
SELECT ?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
`store_id` FROM stores WHERE user_id = ?";
$stmt = $mysqli->prepare($sql);
Bind your $user_id twice. The first one is for your first placeholder and the last one is for your sub-select statement (bind_param)
$stmt->bind_param("iisisiisssi", $user_id, $cat_id, $item_name, $item_code, $item_description, $item_qtty, $item_price, $item_seo_url, $item_image, $item_date, $user_id);
$user_id = $_SESSION['id'];
$cat_id = $cat_id;
$item_name = $item_name;
$item_code = $item_code;
$item_description = $item_description;
$item_qtty = $item_qtty;
$item_price = $item_price;
$store_seo_url = seo_url($item_name);
$item_image = $vtyol;
$item_date = $date;
if($stmt->execute()){
echo " Records created successfully. Redirect to landing page";
$stmt->close();
header("location: index.php");
exit();
} else{
echo "Something went wrong. Please try again later.";
}
And based on your newly added Example 2, the number of columns, placeholders mismatch the number of bind_param again. Also, when you look at your stores table, you have two records under the same user_id. So which store_id you expect to insert to your store table?
I have used LIMIT 1 for now but certainly this is not the correct approach.
$sql = "INSERT INTO products (
user_id, name, salary, store_id
)
SELECT ?, ?, ?, `store_id` FROM stores WHERE user_id = ? LIMIT 1";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("isii", $user_id, $name, $salary, $user_id);
$user_id = 12;
$name = 'john';
$salary = 1200;
if($stmt->execute()){
header("location: index.php");
exit();
} else {
echo "Something went wrong. Please try again later.";
}
$stmt->close();
This is an sql statement with hardcoded values:
$sql = "INSERT INTO products (
user_id, name, salary, store_id
)
SELECT 12, 'john', 1200,
`store_id` FROM stores WHERE user_id = 12 LIMIT 1";
This is same statement with variables:
$sql = "INSERT INTO products (
user_id, name, salary, store_id
)
SELECT $user_id, $name, $salary,
`store_id` FROM stores WHERE user_id = $user_id LIMIT 1";
This is same statement with placeholders:
$sql = "INSERT INTO products (
user_id, name, salary, store_id
)
SELECT ?, ?, ?,
`store_id` FROM stores WHERE user_id = ? LIMIT 1";
$stmt->bind_param("isii", $user_id, $name, $salary, $user_id);
$user_id = 12;
$name = 'john';
$salary = 1200;
I have two tables which store the same data. One is for active users and the other for inactive users. When a user comes, it is searched in the active table and if not found, it is searched in the inactive table. If the user info is found in the inactive table, then it should be moved to active table and deleted from inactive table.
The tables have a column that stores a photograph. When I try to insert the information to active table, I get the following error:
SQLSTATE[22018]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Operand type clash: nvarchar(max) is incompatible with image
I am sure it is caused by the photo because if the user info does not have a photo, the move is successful. But when there is a photo, it fails with the above error.
The SQL that creates the table:
CREATE TABLE [dbo].[tblBackup](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DriverId] [int] NULL,
[FirstNameAmh] [nvarchar](100) NULL,
[FatherNameAmh] [nvarchar](100) NULL,
[GrandNameAmh] [nvarchar](100) NULL,
[Photo] [image] NULL
)
Here is the code:
$dbc->beginTransaction();
$sql = "select * from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$row = $stmt->fetch();
$ins = "insert into tblActive(Id, DriverId, FirstNameAmh, FatherNameAmh, GrandNameAmh, Photo) values(?, ?, ?, ?, ?, ?)";
$st = $dbc->prepare($ins);
$val = array($row['Id'], $row['DriverId'], $row['FirstNameAmh'], $row['FatherNameAmh'], $row['GrandNameAmh'], $row['Photo']);
$st->execute($val);
$sql = "delete from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$dbc->commit();
Edit:
I concluded that the photo data retrieved by PHP is being treated as nvarchar(max) type rather than image type by SQL server. Because of this, SQL server is complaining that it could not insert nvarchar(max) in image data type column. Is there a way to solve this?
If you are in the development phase, I think it would be better to create a stored procedure including "insert select" with "gid" as the parameter and execute it from php. Can't it be a solution for you?
I changed the code a little bit and now it is working. It is seems the problem is cause by prepared statement, though I don't understand why.
$dbc->beginTransaction();
$sql = "select * from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$row = $stmt->fetch();
$ins = "insert into tblActive(Id, DriverId, FirstNameAmh, FatherNameAmh, GrandNameAmh, Photo) values(?, ?, ?, ?, ?, ".$dbc->quote($row['Photo']).")";
$st = $dbc->prepare($ins);
$val = array($row['Id'], $row['DriverId'], $row['FirstNameAmh'], $row['FatherNameAmh'], $row['GrandNameAmh']);
$st->execute($val);
$sql = "delete from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$dbc->commit();
Is it possible in any way to insert an increment of a certain column value ?
$stmt->$this->mysqli->prepare('INSERT INTO `users` ( `email`,`date_added`,`playCount`) VALUES ( ?, NOW(), ? )');
$stmt -> bind_param('si',$email, WHAT); // playCount++ somehow ...
$stmt -> execute();
I know I can use UPDATE to do that, but then I need to check if user exists first and then do INSERT and afterward UPDATE just for one column? There should be a better approach I think?
EDIT: UPDATE also won't work (won't prepare successfully-returns false: any ideas what might be wrong?)
$stmt = $this->mysqli->prepare('UPDATE `users` SET `newsletter` = ?, `date_last` = NOW(), points=points+?, WHERE `email` = ?');
(reference)
"INSERT INTO users ( `email`,`date_added`,`playCount`)
VALUES ( ?, NOW(), (SELECT MAX(playCount) from users)+1 );"
I'm new to php. I have a dropdown option. I want to put an if statement that if one of the options is selected e.g. 'Completed' then I would like it to get the entire record from the MySQL table and move it to another table with the same table structure.
This is what i have so far:
<?php
if( $_GET['status'] = 'Completed' ):
$stmt = $con->prepare("INSERT INTO second_table select * from first_table where id = id;
status = ?,
day_id = ?,
eta = ?,
c_notes = ?
WHERE booking_id = ?");
$stmt->bind_param('sissi',
$_GET['status'],
$_GET['day_id'],
$_GET['eta'],
$_GET['notes'],
$_GET['id']
);
$stmt->execute();
$stmt->close();
?>
If the two tables have the same structures I think your query should be
$stmt = $con->prepare("INSERT INTO second_table VALUES (SELECT * FROM first_table WHERE id = ?");
$stmt->bind_param('i', $_GET['id'] );
Let me know if this didn't work.
I am having a problem with my MySQL.
I have everything setup and all is well, but when I submit my form it will only work if the table is completely empty. It will not submit another entry if there is already information stored in the table.
here is the mysql table
CREATE TABLE student
(StudentID int NOT NULL,
StudentFirst varchar(30),
StudentLast varchar(30),
StudentEmail varchar(254),
StudentPhone varchar(12),
StudentDOB date,
DateStarted date,
LessonID int,
StudentAddress varchar(50),
StudentCity varchar(30),
StudentState char(2),
StudentZip varchar(10),
MusicInterest text);
alter table student add constraint StudentPK primary key AUTO_INCREMENT (StudentID);
alter table student add constraint LessonFK foreign key (LessonID) references lesson(LessonID);
This is my PHP
if(isset($_REQUEST['action'])){
switch($_REQUEST['action']){
case 'submit_student':
$first = $_REQUEST['StudentFirst'];
$last = $_REQUEST['StudentLast'];
$email = $_REQUEST['StudentEmail'];
$phone = $_REQUEST['StudentPhone'];
$dob = $_REQUEST['StudentDOB'];
$datestarted = $_REQUEST['DateStarted'];
$lessonid = $_REQUEST['LessonID'];
$address = $_REQUEST['StudentAddress'];
$city = $_REQUEST['StudentCity'];
$state = $_REQUEST['StudentState'];
$zip = $_REQUEST['StudentZip'];
$musicinterest = $_REQUEST['MusicInterest'];
$stmt = $dbh->prepare("insert into student (StudentFirst, StudentLast, StudentEmail, StudentPhone, StudentDOB, DateStarted, LessonID, StudentAddress, StudentCity, StudentState, StudentZip,MusicInterest) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
$stmt -> bindParam(1,$first);
$stmt -> bindParam(2,$last);
$stmt -> bindParam(3,$email);
$stmt -> bindParam(4,$phone);
$stmt -> bindParam(5,$dob);
$stmt -> bindParam(6,$datestarted);
$stmt -> bindParam(7,$lessonid);
$stmt -> bindParam(8,$address);
$stmt -> bindParam(9,$city);
$stmt -> bindParam(10,$state);
$stmt -> bindParam(11,$zip);
$stmt -> bindParam(12,$musicinterest);
$stmt -> execute();
break;
and my EXTJs
function addStudent(){
Ext.Ajax.request ({
url: 'inc/template.php',
params: {action: 'submit_student',
StudentFirst:firstNameTextField.getValue(),
StudentLast:lastNameTextField.getValue(),
StudentEmail: emailTextField.getValue(),
StudentPhone:phoneNumberTextField.getValue(),
StudentDOB:Ext.util.Format.date(dateOfBirth.getValue(), 'Y-m-d'),
DateStarted:dateStarted.getValue(),
LessonID:dayTypeCombo.getValue(),
StudentAddress:streetTextField.getValue(),
StudentCity:cityTextField.getValue(),
StudentState:stateTextField.getValue(),
StudentZip:zipTextField.getValue(),
MusicInterest:musicInterest.getValue()
},
method: 'POST',
});
tabPanel.activate(studentGrid);
tabPanel.activate(scheduleGrid);
clearStudentForm();
I have no idea why it only submits one time. It is really baffling. It shows the post in firebug.
any help is much appreciated.
I am not sure about AUTO-INCREMENT statement at
alter table student add constraint StudentPK primary key AUTO_INCREMENT (StudentID);
Also i think, you should use this syntax for multiple columns. for one column use
CREATE TABLE student
(StudentID int NOT NULL PRIMARY KEY,
StudentFirst varchar(30),
...