How can I fix this transaction so that the pdo query makes a new table in step #4?
The first three steps work, but I can't seem to get #4 to work.
STEPS
Finds a user with a chattingstatus of 0 in the database
Add a user into the database (with predetermined variables)
change the chattingstatus from 0 to 1 for both the user with a 0 status and the inserted user
4. Create a table with the id of both users as the title like this 2+13 (2 being the id and 13 being the id)
$userid = "123456";
$firstname = "Dae";
$oglang = "engs";
$status = 0;
$pdo->beginTransaction();
try{
// Find a user with a status of 0
$sql = "SELECT id FROM users WHERE chattingstatus = :status";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':status' => $status)
);
$freeuser = $stmt->fetchColumn();
//put the original user into the database with userid firstname and language
$sql = "INSERT INTO users (userid, firstname, oglang, chattingstatus) VALUES (:userid, :firstname, :oglang, :chattingstatus)";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':userid' => $userid, ':firstname' => $firstname, ':oglang' => $oglang, ':chattingstatus' => 0)
);
$ogID = $pdo->lastInsertId();
// change the chattingstatus of 0 of the free user to 1
$sql = "UPDATE users SET chattingstatus = 1 WHERE id = :freeuser";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':freeuser' => $freeuser)
);
//query 3 CHANGE STATUS OF ORIGINAL USER from 0 to 1
$sql = "UPDATE users SET chattingstatus = 1 WHERE userid = :oguser";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':oguser' => $userid)
);
//query 4: Make a table between the 2 users with their IDs
$table = $freeuser."+".$ogID;
$sql ="CREATE table $table(
ID INT( 11 ) AUTO_INCREMENT PRIMARY KEY,
Messages VARCHAR( 50 ) NOT NULL);";
$stmt = $pdo->exec($sql);
print("Created $table Table.\n");
$pdo->commit();
}
//Our catch block
catch(Exception $e){
//Print out the error message.
echo $e->getMessage();
//Rollback the transaction.
$pdo->rollBack();
}
Thanks in advance.
Since your table name includes the special character +, you need to put it in backticks to quote it.
$sql ="CREATE table `$table` (
ID INT( 11 ) AUTO_INCREMENT PRIMARY KEY,
Messages VARCHAR( 50 ) NOT NULL);";
You'll need to remember to put backticks around the table name whenever you use it in other queries. If you insist on having per-user tables like this, you might want to use a different character to connect them, like underscore.
Creating table in transation doesn't work in MySQL:
Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.
Source: https://www.php.net/manual/en/pdo.begintransaction.php
Related
so i have a table of data in web ui
as soon as I click the button. all of the field data in "Status Email" changed. not just selected field that i meant.
this is the sintaks sql
if($mail->Send())
{
$query = "UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE EmailSent = 'Belum Kirim Email'";
$update = $con->prepare($query);
$update->execute();
}
how can i get the "update" only the data that I click on the button??
Get specific field
In order to get the specific field from a MYSQL database
Select column FROM databse WHERE x = y
Example:
SELECT id, firstname, lastname FROM MyGuests WHERE lastname='Doe'
The issue
It's best to get a unique identifier, which no other user has used. For example a 10 digit user id code. Check that this code doesn't exist, for it to be unique.
UPDATE:
Easily use the UNIQUE SQL tag to resolve this issue.
CREATE TABLE X (
ID INT UNIQUE
)
Example:
SELECT id, firstname, lastname FROM MyGuests WHERE id=ryan9273__2
Update a specific field
Now that we have fixed the issue we can easily
UPDATE x SET y=z WHERE id=b
Lets fix your code:
UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE EmailSent = 'Belum Kirim Email'
Lets make it more dynamic
UPDATE nearly_inactive SET :email = :emailaddr WHERE EmailSent = :id
final code:
$query = $con->prepare("UPDATE nearly_inactive SET :email = :emailaddr WHERE EmailSent = :id");
$query->bindParam(':email', $email, PDO::PARAM_STR);
$query->bindParam(':emailaddr', $emailaddr, PDO::PARAM_STR);
$query->bindParam(':id', $id, PDO::PARAM_STR);
$update->execute();
Security Matters
You are using PDO, so use bindParam aswell. Secret code enthusiast answer isn't as secure as the current code i provided!
Practice Makes Perfect
Please don't copy my code right away. learn from it and code it again ! Make it better. Also check the official PHP documentation for more info on these topics
Stay safe !
Regards,
Ryan
you need to determine which record need to be changed based on their unique ID. usually it's the primary key of the table. so, If your primary key is enroller_id, then pass the value of enroller_id, and put it inside your sql.
if($mail->Send())
{
//prepare your query
$statement = $this->mysqli->prepare("UPDATE nearly_inactive SET EmailSent = 'Sudah Kirim Email' WHERE enroller_id = ?");
//check for statement preparation
if ($statement === false) {
trigger_error($this->mysqli->error, E_USER_ERROR);
return;
}
//bind the value
$statement->bindParam("i", $id);
//get id for the query
$id = your_field_enroller_id;
//execute the statement
$statement->execute();
}
where enroller_id is your table primary key, and $id is the value of that field primary key.
<?php
$servername="localhost";
$username="root";
$password="";
$dbname="demon";
//CREATE CONNECTION
$conn=new mysqli($servername,$username,$password,$dbname);
//CHECK CONNECTION
if ($conn->connect_error)
{
die("connection failed:".$conn->connect_error);
}
$sql="UPDATE student set NAME='JohnRambo' where STUDENT_ID=1000";
$result=$conn->query($sql);
if ($result===TRUE)
{
echo"NEW RECORD CREATED SUCCESSFULLY";
}
else
{
echo "ERROR:".$sql."<br>".$conn->error;
}
$conn->close();
?>
Having this query
$query = 'INSERT INTO users(name) VALUES (:name)';
$stmt = $pdo->prepare($query);
$stmt->execute(['name' => $_POST['name']]);
INSERTing into The Table: Users where column name is UNIQUE.
Instead of doing two queries
$check = 'SELECT EXISTS (SELECT name FROM users WHERE name = :name);'
$stmt = $pdo->prepare($check);
$stmt->execute(['name' => $_POST['name']]);
if ($stmt->fetchColumn() == 0) {
$query = 'INSERT INTO users(name) VALUES (:name)';
$stmt = $pdo->prepare($query);
$stmt->execute(['name' => $_POST['name']]);
}
Is it possible using PDO to FETCH the Duplicated row id if $query failed to INSERT? Something like
$query = 'INSERT INTO users(name) VALUES (:name)';
$stmt = $pdo->prepare($query);
$stmt->execute(['name' => $_POST['name']]);
if ($stmt->duplicated() > 0) {
echo "Name already exists by the id number ".$stmt->duplicated()."";
}
In case it is impossible to return the Duplicated ID, Can I just tell if there is a Duplication without returning anything?
Example:
users
[id - name]
[1 - MARX]
[2 - MATH]
$query = 'INSERT INTO users(name) VALUES ('MARX')';
$stmt = $pdo->prepare($query);
$stmt->execute();
if ($stmt->duplicated() > 0) {
echo "Name already exists by the id number ".$stmt->duplicated()."";
} else {
echo "Name was Inserted";
}
Result: Name already exists by the id number 1
Create a unique index on users(name).
Then, catch the error when the unique index is violated.
This has nothing to do with on duplicate key update.
A unique index on name is highly, highly recommended for this purpose. Your code is not thread-safe. Two threads could have the same name. Each could check that it doesn't exist. And each could try to insert it. All that effort -- and you'll get duplicates anyway.
Let the database do what it is supposed to be doing -- protecting your data. Define the unique index/constraint.
So, I have tried to create a table inside my database 'Test',
CREATE TABLE TestTbl(
id INT IDENTITY(1,1),
Agent_id VARCHAR(255) NOT NULL
)
After it was created, I tried to add 2 values for the agent via php, but the result is this:
id | Agent_id
0 8080
0 8081
It does not auto increment, even if I set 'id' as a Primary key, still the problem occurs, anyone knows how to solve this problem?
Here is my insert statement in php, nevermind the $conn, because it works, it is for my sql connection
if(isset($_POST['agentid'])){
$agent = $_POST['agentid'];
$query = "SELECT * FROM [Test].[dbo].[TestTbl] WHERE [Agent_id] = '$agent'";
$result = sqlsrv_query($conn,$query);
if(sqlsrv_has_rows($result) !=0){
echo "ID EXISTS";
}else{
$sql = "SET INDENTITY_INSERT TestTbl ON
INSERT INTO [Test].[dbo].[TestTbl]
([id],[Agent_id]) VALUES ('','$agent')
SET IDENTITY_INSERT TestTbl OFF";
echo "Added";
}}
Change this part
From
INSERT INTO [Test].[dbo].[TestTbl]
([id],[Agent_id]) VALUES ('','$agent')
To
INSERT INTO [Test].[dbo].[TestTbl]
([Agent_id]) VALUES ('$agent')
When it's auto increment, you don't' need to specify that in your INSERT statement.
Also do not SET IDENTITY_INSERT to OFF when you want to use auto increment feature of your table
SET IDENTITY_INSERT allows explicit values to be inserted into the identity column of a table.
Your complete query
if(isset($_POST['agentid'])){
$agent = $_POST['agentid'];
$query = "SELECT * FROM [Test].[dbo].[TestTbl] WHERE [Agent_id] = '$agent'";
$result = sqlsrv_query($conn,$query);
if(sqlsrv_has_rows($result) !=0){
echo "ID EXISTS";
}else{
$sql = "INSERT INTO [Test].[dbo].[TestTbl]
([Agent_id]) VALUES ('$agent')";
echo "Added";
}}
I have a table named "orders" in an SQL database:
id date name orderID
========================
1 1502 John ?
2 1502 Jane ?
The "id" is set to AUTO_INCREMENT and the "date" is created when I insert data via my php form:
if ( !empty($_POST)) {
$name = $_POST['name'];
$valid = true;
if ($valid) {
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO orders (name,date) values(?,CURDATE())";
$q = $pdo->prepare($sql);
$q->execute(array($name));
Database::disconnect();
}
}
I wish that the value for "orderID" is created automatically from the values "id" and "date":
id date name orderID
========================
1 1502 John 15021
2 1502 Jane 15022
Due to the fact, that the id is an AUTO_INCREMENT you have no hand on this value. But it's quite simple. Add a AFTER INSERT trigger to the table and let it update the orderID column afterwards.
Here a quick example of a AFTER UPDATE trigger.
CREATE TRIGGER yourTrigger
AFTER INSERT
ON yourTable FOR EACH ROW
BEGIN
UPDATE yourTable
SET orderid = CAST(date as char(4)) + CAST(id as char(1))
WHERE ID = NEW.id
END;
Don't create another column in your database to hold this value, it's just duplicated data and will only serve to take up unnecessary space.
When you are retrieving data you can use CONCAT(id, date) AS orderid to get the concatenated value.
For example, to get all orderids for John:
SELECT CONCAT(id,date) AS orderid from `orders` WHERE `name`="John"
SET #last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO orders (name,date,orderID) values(?,CURDATE(),#last_id_in_table1 )
try
if ($valid) {
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO orders (name,date) values(?,CURDATE())";
$q = $pdo->prepare($sql);
$q->execute(array($name));
$q = $pdo->prepare( '
update orders
set orderId = id
where id = SELECT LAST_INSERT_ID()'
);
$q->execute();
Database::disconnect();
}
should work now
I have two tables: phpbb_sn_fms_groups and phpbb_fms_user_groups, which I would like to INSERT into using the two queries below, however the first problem is I can't possibly manually run the two queries ~1000 times for each user_id (56 through 1060). The second problem is I need to INSERT the auto incremented fms_gid from the first query (table: phpbb_sn_fms_groups) into fms_id from the second query (table: phpbb_sn_fms_users_group) when the php script INSERTs each user_id.
// user_id: 56 through 1060
// fms_gid in the table phpbb_sn_fms_users_group needs the unique fms_gid for each row from the table phpbb_sn_fms_groups because it doesn't autoincrement.
$result = mysql_query("INSERT INTO phpbb_sn_fms_groups (fms_gid, user_id, fms_name, fms_clean, fms_collapse) VALUES ('autoincrementednumberthatdoesntneedtobeinserted', '56', 'Staff', 'staff', '0')")
or die(mysql_error());
$result = mysql_query("INSERT INTO phpbb_sn_fms_users_group (fms_gid, user_id, owner_id) VALUES ('inserttheautoincrementednumberfromfms_gidinphpbb_sn_fms_groups', '2', '56')")
or die(mysql_error());
Any help would be appreciated. Thanks!
This is a great time for PDO.
See http://php.net/manual/en/book.pdo.php for connection info but something like
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
// First select the users you need query.
$stmt = $pdo->prepare("SELECT id, name FROM users WHERE id BETWEEN 56 AND 1060");
$stmt->execute();
$result = $stmt->fetchAll();
OR if literally 56 through 1060 you can use a for loop.
Then loop through those results to execute
foreach($result as $row) {
$stmt1 = $pdo->prepare("INSERT INTO phpbb_sn_fms_groups (fms_gid, user_id, fms_name, fms_clean, fms_collapse) VALUES ('autoincrementednumberthatdoesntneedtobeinserted', :user_id , 'Staff', 'staff', '0')");
$stmt1->bindParam(":user_id", $row['id']);
$stmt1->execute();
//get last inserted id.
$inserted_id = $pdo->lastInsertId();
$stmt2 = $pdo->prepare("INSERT INTO phpbb_sn_fms_users_group (fms_gid, user_id, owner_id) VALUES (:last_id, '2', :user_id)");
$stmt2->bindParam(":last_id", $inserted_id);
$stmt2->bindParam(":user_id", $row['id']);
$stmt2->execute();
}
Hope this gets you started. Can also be done in mysqli. Don't want to jump into that debate. I just like naming the parameters for binding.