MySQL Transaction+ PHP issue in Mysql - php

I have a code which was used in an application where I am having a problem in rollback. Even if I 's2' returns false rollback isn't happening i.e. table 'products' is getting droped.
Can anyone explain why it isn't working or how should I change it.
Note: tables are of Innodb engine..I use mysql 5.0+
mysql_query('SET AUTOCOMMIT=0;');
mysql_query('START TRANSACTION;');
$sql = 'DROP TABLE '.$this->Product->tablePrefix.'products';
$s1 = mysql_query($sql);
$sql = 'RENAME TABLE '.$this->Product->tablePrefix.'temp12212 TO '.$this->Product->tablePrefix.'products';
$s2 =mysql_query($sql);
if($s1 && $s2){
mysql_query('COMMIT;');
$this->Session->setFlash('Commit Successful to Database');
}else{
mysql_query('ROLLBACK;');
$this->Session->setFlash('Commit failed due to some errors<br> auto-rollbacked to previous state');
}

DROP TABLE is one of the commands in MySql that cause a implicit commit.
http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html
Use this instead:
'RENAME TABLE '.$this->Product->tablePrefix.'products TO backup_table
, '.$this->Product->tablePrefix.'temp12212 TO '.$this->Product->tablePrefix.'products';

You cannot rollback a DROP TABLE or RENAME TABLE statement as they cause an implicit commit.

I sorted the problem this way instead!!! thanks all for your reply :-)
$sql = 'DROP TABLE IF EXISTS '.$this->Product->tablePrefix.'temp_backup';
mysql_query($sql);
$sql = 'RENAME TABLE '.$this->Product->tablePrefix.'products TO '.$this->Product->tablePrefix.'temp_backup, '.$this->Product->tablePrefix.'temp TO '.$this->Product->tablePrefix.'products';
$status =mysql_query($sql);
if($status){
$sql = 'DROP TABLE '.$this->Product->tablePrefix.'temp_backup';
mysql_query($sql);
$this->Session->setFlash('Commit Successful to Database');
}else{
$this->Session->setFlash('Commit failed due to some errors<br> auto-rollbacked to previous state');
}

Related

How to INSERT in one table and UPDATE in another in single QUERY?

I'm currently creating some sort of inventory system.
I have master_tbl where in I save the items. In master_tbl, I have column qty_left or the available stock left.
I also have the table issuance_tbl where in I save all the transaction in issuing items.
In this table there is issued_qty.
My problem is how can I INSERT a row into issuance_tbl at the same time UPDATE the master_tbl.qty_left. (master_tbl.qty_left - issuance_tbl.issued_qty).
Is it possible?
I think the best way is using Stored Procedure. You can have bunch of SQL statements with error handling and ACID transactions in one place. This is because if your first query executes and the second fails, you may need to rollback transactions. Stored procedures allow all this fancy but reliable stuff.
You can start here: http://forums.mysql.com/read.php?98,358569
I'm not completely confident that 'If there's any way to do such thing':
You need to do it in steps, LIKE THIS:
$result = $this->db->insert($table);//Example function to insert inventory item
$insert_id = $this->db->insert_id();//Example function to get the id of inserted item
if($result)
$res = $this->db->update($id,$data,$table);//Example function to update data of quantity table
if(!$res)
{
$this->db->delete($insert_id,$table);s
$result = '-1';
}
return $result;
Hope this might help
here is the example:
<form method="post">
QTY:<input type="text" name="qty_left"></input>
<input type="submit" name="submit" value="update"></form>
<?php
////////your config db
$qty = $_POST['qty_left'];
if(isset($_POST['submit']);
$sql = mysql_query("insert into issuance_tbl (issued_qty) values (".$qty.") ");
$sql1 = mysql_query("update master_table set qty_left= ".$qty."");
?>
$con = mysqli_connect($host, $user, $password, $database);
...
$issued_qty = '10'; //some value
$insert_query = "insert into issuance_table (issued_qty, ...) values ('$issued_qty', ... ) ;";
$update_query = "update master_tbl set qty_left = (qty_left - ".$issued_qty.") where ....";
mysqli_multi_query($con, $insert_query.$update_query);

Trouble executing multiple-table mysql query from PHP

I am attempting to match rows in a mysql table using the values from table1.column1 and table2.column3 and then copy the value from table2.column2 into table1.column1 for each match. The query below does what I need to do, but only when I execute it manually (through phpmyadmin). When I try to execute it from PHP I receive the error Unknown column table1.column1 in 'field list'. Here is my PHP code:
<?php
mysql_connect($host,$user,$pass);
$db_selected = mysql_select_db($data);
$sql = "UPDATE table1 t1, table2 t2
SET t1.column1 = t2.column2
WHERE t1.column1 = t2.column3";
$result = mysql_query($sql);
if (!$result) {
echo mysql_error();
} ?>
I know that the mysql connection info works because I am able to execute other queries. From my research on the error it seems that I might need backticks around some part of the query but after several tries I can't figure out the correct way.
EDIT 1 - As requested here is the real query:
UPDATE wp_mf_custom_groups,wp_mf_posttypes
SET wp_mf_custom_groups.post_type=wp_mf_posttypes.type
WHERE wp_mf_custom_groups.post_type=wp_mf_posttypes.id
Outputs the error
Unknown column 'wp_mf_custom_groups.post_type' in 'field list'
Additional information I just realized might be conflicting with it. Before this happens I also renamed the table using:
RENAME TABLE wp_mf_module_groups TO wp_mf_custom_groups
Maybe since the table was just renamed it cant reference it?
Worked when I added backticks to the columns only after WHERE
UPDATE wp_mf_custom_groups,wp_mf_posttypes
SET wp_mf_custom_groups.post_type=wp_mf_posttypes.type
WHERE wp_mf_custom_groups.`post_type=wp_mf_posttypes.id
If query works with PHPmyadmin try this
<?php
$con = mysql_connect($host,$user,$pass) or die('Failed to connect');
$db_selected = mysql_select_db('db_name', $con);
$sql = "UPDATE table1 t1, table2 t2
SET t1.column1 = t2.column2
WHERE t1.column1 = t2.column3";
$result = mysql_query($sql, $con);
if (!$result) {
echo mysql_error();
} ?>

PHP/MYSQL - Check whether it have duplicated record before inserting new record

Suppose I have a table called "device" as below:
device_id(field)
123asf15fas
456g4fd45ww
7861fassd45
I would like to use the code below to insert new record:
...
$q = "INSERT INTO $database.$table `device_id` VALUES $device_id";
$result = mysql_query($q);
...
I don't want to insert a record that is already exist in the DB table, so how can I check whether it have duplicated record before inserting new record?
Should I revise the MYSQL statement or PHP code?
Thanks
UPDATE
<?php
// YOUR MYSQL DATABASE CONNECTION
$hostname = 'localhost';
$username = 'root';
$password = '';
$database = 'device';
$table = 'device_id';
$db_link = mysql_connect($hostname, $username, $password);
mysql_select_db( $database ) or die('ConnectToMySQL: Could not select database: ' . $database );
//$result = ini_set ( 'mysql.connect_timeout' , '60' );
$device_id = $_GET["device_id"];
$q = "REPLACE INTO $database.$table (`device_id`) VALUES ($device_id)";
$result = mysql_query($q);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
?>
Since I understood well your question you have two ways to go, it depends how you would like to do the task.
First way -> A simple query can returns a boolean result in the device_id (Exists or not) from your database table. If yes then do not INSERT or REPLACE (if you wish).
Second Way -> You can edit the structure of your table and certify that the field device_id is a UNIQUE field.
[EDITED]
Explaining the First Way
Query your table as follow:
SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'
then if you got results, then you have already that data stored in your table, then the results is 1 otherwise it is 0
In raw php it looks like:
$result = mysql_query("SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'");
if (!$result)
{
// your code INSERT
$result = mysql_query("INSERT INTO $database.$table `device_id` VALUES $device_id");
}
Explaining the Second Way
If your table is not yet populated you can create an index for your table, for example go to your SQL command line or DBMS and do the follow command to your table:
ALTER TABLE `your_table` ADD UNIQUE (`device_id`)
Warning: If it is already populated and there are some equal data on that field, then the index will not be created.
With the index, when someone try to insert the same ID, will get with an error message, something like this:
#1062 - Duplicate entry '1' for key 'PRIMARY'
The best practice is to use as few SQL queries as possible. You can try:
REPLACE INTO $database.$table SET device_id = $device_id;
Source

How to drop all tables in database without dropping the database itself?

I would like to delete all the tables from database, but not deleting the database itself. Is it possible ? I'm just looking for shorter way than removing the database and create it again. Thanks !
The shortest is to re-create database. but if you don't want to...
This is for MySQL/PHP. Not tested but something like that.
$mysqli = new mysqli("host", "my_user", "my_password", "database");
$mysqli->query('SET foreign_key_checks = 0');
if ($result = $mysqli->query("SHOW TABLES"))
{
while($row = $result->fetch_array(MYSQLI_NUM))
{
$mysqli->query('DROP TABLE IF EXISTS '.$row[0]);
}
}
$mysqli->query('SET foreign_key_checks = 1');
$mysqli->close();
There is no simple way to do this. Either you'll need to know what the tables are in advance:
//edit you can get this information using the query SHOW TABLE STATUS
$tables = array('users','otherdata');
foreach($tables as $table){
db.execute("DROP TABLE "+$table);
}
or you can drop the database and re-create it empty (it's really not that much effort!):
db.execute('DROP DATABASE SITEDATA');
db.execute('CREATE DATABASE SITEDATA');
You'd have to drop every table in the db separately, so dropping the database and recreating it will actually be the shortest route (and the fastest one for that matter).
When I had to do this in Oracle, I would write a select statement that would generate the drop table statements for me. Something to the effect of:
Select 'DROP TABLE ' || table_name || ';' from user_tables;
I could then pipe the output of the select statement to a file. After I ran this, I would have a file that would drop all my tables for me. It would look something like:
DROP TABLE TABLE1;
DROP TABLE TABLE2;
DROP TABLE TABLE3;
etc...
Not a mysql expert, but I would imagine it would have a similar facility to both select all tables for a schema, as well as direct output from a SQL statement to a file.
Use SHOW TABLE STATUS to get all tables in your database, then loop over result and drop them one by one.
There are some solutions here in comments: http://dev.mysql.com/doc/refman/5.1/en/drop-table.html
I needed to drop all tables except a couple from an inadvertent dump.
A PHP function to drop all tables except some (adapted from here), for anyone else who might need:
<?php
$mysqli = new mysqli( "localhost", "user", 'password', "database");
function drop_all_tables($exceptions_array, $conn) {
$exceptions_string="('" ;
foreach ($exceptions_array as $table) {
$exceptions_string .=$table . "','";
}
$exceptions_string=rtrim($exceptions_string, ",'");
$exceptions_string .="')" ;
$sql="SELECT CONCAT('DROP TABLE ', TABLE_NAME, '; ')
FROM information_schema.tables
WHERE table_schema = DATABASE() AND table_name NOT IN $exceptions_string";
$result=$ conn->query($sql);
while($row = $result->fetch_array(MYSQLI_NUM)) {
$conn->query($row[0]);
}
}
//drop_all_tables(array("table1","table2","table3","table4"), $mysqli);
?>
A procedural way to do this is as follows:
$query_disable_checks = 'SET foreign_key_checks = 0';
$query_result = mysqli_query($connect, $query_disable_checks);
// Get the first table
$show_query = 'Show tables';
$query_result = mysqli_query($connect, $show_query);
$row = mysqli_fetch_array($query_result);
while ($row) {
$query = 'DROP TABLE IF EXISTS ' . $row[0];
$query_result = mysqli_query($connect, $query);
// Getting the next table
$show_query = 'Show tables';
$query_result = mysqli_query($connect, $show_query);
$row = mysqli_fetch_array($query_result);
}
Here $connect is just the connection made with mysqli_connect();.
You can execute this. Just add more tables if I missed any
drop table wp_commentmeta;
drop table wp_comments;
drop table wp_links;
drop table wp_options;
drop table wp_postmeta;
drop table wp_posts;
drop table wp_term_relationships;
drop table wp_term_taxonomy;
drop table wp_termmeta;
drop table wp_terms;
drop table wp_usermeta;
drop table wp_users;
The single line query to drop all tables, as below:
$dbConnection = mysqli_connect("hostname", "username", "password", "database_name");
$dbConnection->query('SET foreign_key_checks = 0');
$qry_drop = "DROP TABLE IF EXISTS buildings, business, computer, education, fashion, feelings, food, health, industry, music, nature, people, places, religion, science, sports, transportation, travel";
$dbConnection->query($qry_drop);
$mysqli->query('SET foreign_key_checks = 1');
$mysqli->close();

Empty database in MySQL and PHP?

Is it possible to empty an entire database by connecting to it with PHP and giving a command?
The simplest way to do it, if you have the privileges, is:
DROP DATABASE dbName;
CREATE DATABASE dbName;
USE DATABASE dbName;
The alternative is to query the information_schema database for triggers, stored routines (procedures and functions), tables, views and possibly something else, and drop them individually.
Even after this, your database might still not be in the same state as a newly created one, since it might have a custom default character set and collation set. Use ALTER DATABASE to change that.
As features keep getting added (events...) you'll have more and more work this way. So really, the only way to completely empty the database is to drop it and re-create it.
You can get table names with
SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your db'
And make the truncate,
even, you can make
SELECT 'TRUNCATE TABLE ' + table_name + ';' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your db'
And then iterate the resultset executing the string query for each record.
You can get a list of all tables in a database ($databaseName), loop through them all, and apply TRUNCATE TABLE to each.
$result = mysqli_query($link, "SHOW TABLES IN `$databaseName`");
while ($table = mysqli_fetch_array($result)) {
$tableName = $table[0];
mysqli_query($link, "TRUNCATE TABLE `$databaseName`.`$tableName`");
if (mysqli_errno($link)) echo mysqli_errno($link) . ' ' . mysqli_error($link);
else echo "$tableName was cleared<br>";
}
This clears the contents of all the tables in a database, keeping the structure.
Yes. Basically, you need to get a list of all Tables in the Database, then iterate over that list and issue a TRUNCATE TABLE $tablename for each entry.
This looks like a decent enough implementation: Truncate all tables in a MySQL database
This worked for me.
mysql -u < DB-USER > -p<DB-PASS> --silent --skip-column-names -e "SHOW TABLES" <DB-NAME> | xargs -L1 -I% echo 'DROP TABLE `%`;' | mysql -u < DB-USER > -p< DB-PASS > -v < DB-NAME >
<?php
$connection = new mysqli($host, $user, $pass, $db);
$sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA LIKE '".$db."'";
$result = $connection->query($sql);
$tables = $result->fetch_all(MYSQLI_ASSOC);
foreach($tables as $table) {
$sql = "TRUNCATE TABLE `".$table['TABLE_NAME']."`";
$result = $connection->query($sql);
}
?>
Yes. You can connect the database and Truncate the table by assigning as a variable.
$conn = new mysqli($servername, $username, $password, $dbname);
$variableName = $conn->query($que);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$result = $conn->query('TRUNCATE TABLE yourtablename;');
if ($result) {
echo "Request ID table has been truncated";
}
else echo "Something went wrong: " . mysqli_error();

Categories