In MySql using InnoDB, in the context of one transaction, are the inserts supposed to be visible by the following selects?
Example :
$connect = new PDO('mysql:host='. getConfig()->get('DB_HOST').';dbname='. getConfig()- >get('DB_NAME'), getConfig()->get('DB_USER'), getConfig()->get('DB_PASSWORD'), array(PDO::ATTR_PERSISTENT => true));
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$connect->beginTransaction();
$sql = 'INSERT INTO t_table (label) VALUES ("test") WHERE id = "1"';
$query = $connect->prepare($sql);
$query ->execute();
$sql2='SELECT * FROM t_table';
$query2=$connect->prepare($sql2);
$query2->execute();
$result = $query2->fetch();
$connect->commit();
In this case, should 'test' be in $result? if not, how could I make it do so?
Precision: the column 'label' is not the primary key but has an index.
Yes, 'test' must be in $result.All operations in a single transaction are visible to each other.
Related
Assuming that I have two tables, names and phones,
and I want to insert data from some input to the tables, in one query. How can it be done?
You can't. However, you CAN use a transaction and have both of them be contained within one transaction.
START TRANSACTION;
INSERT INTO table1 VALUES ('1','2','3');
INSERT INTO table2 VALUES ('bob','smith');
COMMIT;
http://dev.mysql.com/doc/refman/5.1/en/commit.html
MySQL doesn't support multi-table insertion in a single INSERT statement. Oracle is the only one I'm aware of that does, oddly...
INSERT INTO NAMES VALUES(...)
INSERT INTO PHONES VALUES(...)
Old question, but in case someone finds it useful... In Posgresql, MariaDB and probably MySQL 8+ you might achieve the same thing without transactions using WITH statement.
WITH names_inserted AS (
INSERT INTO names ('John Doe') RETURNING *
), phones_inserted AS (
INSERT INTO phones (id_name, phone) (
SELECT names_inserted.id, '123-123-123' as phone
) RETURNING *
) SELECT * FROM names_inserted
LEFT JOIN phones_inserted
ON
phones_inserted.id_name=names_inserted.id
This technique doesn't have much advantages in comparison with transactions in this case, but as an option... or if your system doesn't support transactions for some reason...
P.S. I know this is a Postgresql example, but it looks like MariaDB have complete support of this kind of queries. And in MySQL I suppose you may just use LAST_INSERT_ID() instead of RETURNING * and some minor adjustments.
I had the same problem. I solve it with a for loop.
Example:
If I want to write in 2 identical tables, using a loop
for x = 0 to 1
if x = 0 then TableToWrite = "Table1"
if x = 1 then TableToWrite = "Table2"
Sql = "INSERT INTO " & TableToWrite & " VALUES ('1','2','3')"
NEXT
either
ArrTable = ("Table1", "Table2")
for xArrTable = 0 to Ubound(ArrTable)
Sql = "INSERT INTO " & ArrTable(xArrTable) & " VALUES ('1','2','3')"
NEXT
If you have a small query I don't know if this is the best solution, but if you your query is very big and it is inside a dynamical script with if/else/case conditions this is a good solution.
my way is simple...handle one query at time,
procedural programming
works just perfect
//insert data
$insertQuery = "INSERT INTO drivers (fname, sname) VALUES ('$fname','$sname')";
//save using msqli_query
$save = mysqli_query($conn, $insertQuery);
//check if saved successfully
if (isset($save)){
//save second mysqli_query
$insertQuery2 = "INSERT INTO users (username, email, password) VALUES ('$username', '$email','$password')";
$save2 = mysqli_query($conn, $insertQuery2);
//check if second save is successfully
if (isset($save2)){
//save third mysqli_query
$insertQuery3 = "INSERT INTO vehicles (v_reg, v_make, v_capacity) VALUES('$v_reg','$v_make','$v_capacity')";
$save3 = mysqli_query($conn, $insertQuery3);
//redirect if all insert queries are successful.
header("location:login.php");
}
}else{
echo "Oopsy! An Error Occured.";
}
Multiple SQL statements must be executed with the mysqli_multi_query() function.
Example (MySQLi Object-oriented):
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO names (firstname, lastname)
VALUES ('inpute value here', 'inpute value here');";
$sql .= "INSERT INTO phones (landphone, mobile)
VALUES ('inpute value here', 'inpute value here');";
if ($conn->multi_query($sql) === TRUE) {
echo "New records created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
?>
I'm breaking my brains over this, i would realy appriciate help!
This is the code i have so far..
$conn = db_connect();
$sql = "INSERT INTO measurements
(`date`, `weight`, `waist`, `id`) VALUES (?,?,?,?)";
$stmt = $conn-> prepare($sql);
$stmt ->bind_param("sddi", $date, $_POST['weight'], $_POST['waist'], $user_id);
$stmt->execute();
$stmt->close();
$conn->close();
Its a prepared statement for an sql insert. Now i want to change it to a IF EXIST THEN UPDATE ELSE insert the way i am doing right now. something like this but then with a prepared statement:
IF EXISTS
(SELECT * FROM measurements WHERE user_id=’4’)
UPDATE measurements SET (`weight`=40, `waist`=45) WHERE user_id=’4’
ELSE
INSERT INTO measurements
VALUES (`date`='week 1', `weight`= 40, `waist`=45, `id`=4)
I found some articles on stackoverflow about the if EXIST then update else insert but i did not find it with a prepared statement in it that worked for me.
Thanks a thousand!
UPDATE:
i've changed it to dublicate key style.
$sql = "
INSERT INTO measurements (uniqueID, date, weight, waist)
VALUES ('$uniqueID', '$date', '$weight', '$waist')
ON DUPLICATE KEY UPDATE weight= '$weight', waist= '$waist'";
$conn->query($sql);
Now the second part of the question, how do i make this a prepared statement?
To implement Mr. Jones' solution as a mysqli prepared statement, you would code it thus:
$sql = "INSERT INTO measurements
(`uniqueID`, `date`, weight, waist)
VALUES
(?, ?, ?, ?)
ON DUPLICATE KEY
UPDATE weight = ?, waist = ?";
$stmt = $conn->prepare($sql);
$stmt ->bind_param("isdddd", $user_id, $date, $_POST['weight'], $_POST['waist'], $_POST['weight'], $_POST['waist']);
$stmt->execute();
A slightly cleaner implementation would be to use PDO:
$sql = "INSERT INTO measurements
(`uniqueID`, `date`, weight, waist)
VALUES
(:uniqueId, :date, :weight, :waist)
ON DUPLICATE KEY
UPDATE weight = :weight, waist = :waist";
/* $conn is a PDO object */
$stmt = $conn->prepare($sql);
$stmt->execute(array(':uniqueId' => $user_id, ':date' => $date, ':weight' => $_POST['weight'], ':waist' => $_POST['waist']));
Note that with named placeholders, you can use the same name in more than one place and only need to assign the value once.
MySQL's approach to this is INSERT ... ON DUPLICATE KEY UPDATE .... It works well; in particular it avoids race conditions if more than one database connection tries to hit the same row.
This requires the table that's the target of your UPSERT to have a meaningful unique index or primary key. It looks like your id is that key.
You can absolutely use parameter binding to present data to this.
You can read about it here. http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
In my database there is a table, that contains only one row: id. It's something like a facade for another table:
Now I want to add an entry into whatever_set, in order to be able to create entries in the dependent tables. In SQL I would write:
INSERT INTO whatever_set VALUES ();
But when I try it with Zend\Db
$action = new Insert(whatever_set');
$data = [];
$action->values($data);
$sql = new Sql($this->dbAdapter);
$statement = $sql->prepareStatementForSqlObject($action);
$result = $statement->execute();
I get an exception:
values or select should be present
There are some possible workarounds (see below). But is there though a "Zend way" to save empty with no VALUES? How to do this?
Workaround 1
Custom Insert class.
Workaround 2
Raw SQL like
$sql = 'INSERT INTO whatever_set VALUES ();';
$result = $this->dbAdapter->getDriver()->getConnection()->execute($sql);
Please i have this quetion,
I have here:
$query = $db->prepare('Update survey_content set '.$type.' = '.$type.'+1 where id = '.$where);
$query->execute();
I'm new to PDO and i really don't know how to create a new query, i need to add a record on the database, is it ok like this?
$query1 = $db->prepare('INSERT INTO daily (selected)
VALUES (.$type.)');
$query1->execute();
Use a placeholder and fill the value in the execute method
$query1 = $db->prepare("INSERT INTO daily (selected)
VALUES (?)");
$query1->execute($selected_data);
or bind the parameter seperately
$query1 = $db->prepare("INSERT INTO daily (selected)
VALUES (:sel_dat)");
$query1->bindParam(":sel_dat",$selected_data);
$query1->execute();
I am using Zend Framework. I have tree tables. Users and Groups and one table linking them.
I want to increment a field from users of a given group. To increment one User I do:
$table = 'users';
$update = array(
'ACLVersion' => new Zend_Db_Expr('ACLVersion + 1')
);
$where[] = $db->quoteInto('id = ?', $user);
$db->update($table, $update, $where);
I tried to use multiple wheres.
I have no clue how to join the tables in a where with Zend.
To use a JOIN with Zend_Db_Table, you have to disable the integrity check.
See example #27 in the ZF Reference Guide for Zend_Db_Table:
$table = new Bugs();
// retrieve with from part set, important when joining
$select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->setIntegrityCheck(false)
->where('bug_status = ?', 'NEW')
->join('accounts', 'accounts.account_name = bugs.reported_by')
->where('accounts.account_name = ?', 'Bob');
$rows = $table->fetchAll($select);
Note that disabling the integrity check will also disable some of the automagic of the resulting recordset:
The resulting row or rowset will be
returned as a 'locked' row (meaning
the save(), delete() and any
field-setting methods will throw an
exception).
Load $num with a array of id's from a given group
The following code will do the job
$table = 'users';
$update = array(
'ACLVersion' => new Zend_Db_Expr('ACLVersion + 1')
);
$where = $db->quoteInto('id IN (?)', $num);
$db->update($table, $update, $where);