PHP MYSQL insert Data into 2 tables - php

Hey All I currently have a problem with my insert php file
I have a form.. where the user types in details.. for my form.. event name, event date and location
basically the bit that is working
is
well first of all i would like to add an entry into 2 tables: events and results
it's having no problems adding the entry into events
but it doesnt add the same entry into "results"
the events table had the following columns: Event ID, Event Name, Event Date and Location
The Results table has: Event ID, Member ID, Event Name, Score and Place
The Event ID is auto increment
so it auto assigns an ID to it
and its applied to both tables
the auto increment in Event ID
the bit thats working is
inserting entry into the events table
but because the events table and results table both have "Event Name
I want this php to fully insert details for the event table
BUT also at the same time, just insert the eventname into the results table
but the EventID in events has to be the same generated number as EventID in results..
Below is my code: All help really appreciated!!!
<?
$pdo = new PDO('mysql:host=localhost;dbname=clubresults', 'root', '12345678');
#Set Error Mode to ERRMODE_EXCEPTION.
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $pdo->query('SELECT EventID, EventName, EventDate, Location from events');
$rowset = array();
if ($query) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
// Build array of rows
$rowset[] = $row;
}
// Output header first
$headrow = $rowset[0];
print("<table border=\"1\">\n<tr>\n");
// Use $rowset[0] to write the table heading
foreach ($headrow as $col => $val) {
printf("<th>%s</th>\n", $col);
}
print("</tr>");
// Then output table rows.
// Outer loop iterates over row
foreach ($rowset as $row) {
print("<tr>");
// Inner loop iterates over columns using $col => $val
foreach ($row as $col => $val) {
// We don't know your column names, but substitute the first column (the ID) for FIRSTCOL here
printf("<td>%s</td>\n", $row['EventID'],$val);
}
print("</tr>");
}
}
print("</table>");
?>
</form>
</div>
<?
$pdo = new PDO('mysql:host=localhost;dbname=clubresults', 'root', '12345678');
#Set Error Mode to ERRMODE_EXCEPTION.
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt=$pdo->prepare('INSERT INTO events (EventName, EventDate, Location)
VALUES (:EventName, :EventDate, :Location)');
$stmt->bindValue(':EventName', $_POST['EventName']);
$stmt->bindValue(':EventDate', $_POST['EventDate']);
$stmt->bindValue(':Location', $_POST['Location']);
$stmt->execute();
?>
<?
$int_event_id = $_GET["EventID"];
if((int)$int_event_id)
{
$stmt=$pdo->prepare('INSERT INTO results (EventName, EventID)
VALUES (:EventResultsName, $int_event_id)');
$stmt->bindValue(':EventName', $_POST['EventResultsName']);
$stmt->execute();
}
?>

If the inserts are always taking place in sequence, I'd use $pdo->lastInsertId() (see: http://www.php.net/manual/en/pdo.lastinsertid.php)
So, I think this line is wrong:
$int_event_id = $_GET["EventID"];
I'd write it like this:
<?
$stmt = $pdo->prepare('
INSERT INTO results (EventName, EventID)
VALUES (:EventResultsName, :EventId)
');
$stmt->bindValue(':EventName', $_POST['EventResultsName']);
$stmt->bindValue(':EventId', $pdo->lastInsertId());
$stmt->execute();
?>
Note that this assumes the insert into results occurs immediately after the insert into events.
You could've done the same thing without a bind variable using MySQL's native last_insert_id() function, like this:
<?
$stmt = $pdo->prepare('
INSERT INTO results (EventName, EventID)
VALUES (:EventResultsName, last_insert_id())
');
$stmt->bindValue(':EventName', $_POST['EventResultsName']);
$stmt->execute();
?>
However, this is less portable than the previous example. However, pdo's lastInsertId() isn't exactly RDBMS agnostic either (see docs) so you'd have to fix this piece of code anyway if you're thinking of targeting another RDBMS

Assuming that the Event entity represents an event and the Result entity represents an outcome of an event for a particular member. So there is a 1->n relationship between Event -> Result
Problem
This means that sometimes you will get a request where both Event and Result data needs to be inserted, while at others there will only be Result data. In this latter case you will be able to get EventId from the request _GET[EventId].
In the first case, you will not have this EventId set and since you are executing the second insert based on the check if((int)$int_event_id), the Result will never be inserted.
Solution
The first thing you should do is check if _GET["EventId"] isset. If it isn't then you need to both insert an Event and Result. In this case the EventId will be fetched from the last inserted statement as follows:
$pdo->lastInsertId()
While if the `_GET["EventId"] isset, you should only do the second insertion as you are doing.

Related

INSERT INTO SELECT with VALUES in one query

Bit new to MYSQL and PHP - I have the following code that will create a new record in multiple tables that I have setup however I need to merge the following code together somehow as it creates separate rows instead of one record
$sql .=("INSERT INTO orders (customer_id) SELECT customer_id FROM
customer_details;");
foreach($result as $item){
$mysql_desc = $item['product_description'];
$mysql_mode = $item['delivery_mode'];
$mysql_cost = $item['course_cost'];
$sql .=("INSERT INTO orders(product_description, delivery_mode, course_cost) VALUES('$mysql_desc', '$mysql_mode', '$mysql_cost');");
}
The result I'm getting:
Based on your data I assume that you want to insert the customer id and the values from php into the same record. In this case you need to combine them into the same insert ... select ... statement:
$sql .=("INSERT INTO orders(customer_id, product_description, delivery_mode, course_cost) select customer_id, '$mysql_desc', '$mysql_mode', '$mysql_cost' from customer_details;");
Couple of things to note:
This insert ... select ... statement will insert the same records for all customers in the customer details table. I'm not sure if this is your ultimate goal.
Pls consider the advices made in the comments regarding the old mysql API and the use of prepared statements.
To put this more into what I would expect to happen, something along the lines of - prepare statement, then loop through each item and add in new row...
$insert = $connection->prepare("INSERT INTO orders (customer_id,product_description, delivery_mode, course_cost)
VALUES (?,?,?,?)");
foreach($result as $item){
$customerID = 1; // Have to ensure this is what your after
$mysql_desc = $item['product_description'];
$mysql_mode = $item['delivery_mode'];
$mysql_cost = $item['course_cost'];
$insert->execute([customerID,mysql_desc,mysql_mode,mysql_cost]);
}

php insert mysql with while loop

i want to get datas from a mySQL table and want to insert every row (that my query get) into another table.
With following code i get my Datas:
$cart = new Dbconn();
$query = new Dbconn();
if ($cart->pdo()) {
$cart->stmt("SELECT id, product FROM cart WHERE uid =:uid");
$cart->bindParam(':uid', Session::get('uid'));
$cart->exe();
}
After i get the data i want to insert it, with a while loop
while ($rowPay = $cart->fetch()) {
if ($query->pdo()) {
$query->stmt('INSERT INTO orders (products_id, order_id) VALUES(:uid, :products)');
$query->bindParam(':user_id', Session::get('uid'));
$query->bindParam(':products', $rowPay['product']);
$query->exe();
}
}
He get all Datas but insert only the first entry. Where is my mistake?
Greetings
If it insert only the first entry, then there is a problem with the parameters you try to insert.
You probably try to insert several rows with the same primary key.
I need to know where is the primary key in each table in order to help you more.
$payCart->fetch() fetches single row and $payCart->fetchAll() fetches all rows.
Try as this
while ($rowPay = $payCart->fetchAll(PDO::FETCH_ASSOC)) {
if ($query->pdo()) {
$query->stmt('INSERT INTO orders'
.'(products_id, order_id)'
.'VALUES(:uid, :products)');
$query->bindParam(':user_id', Session::get('uid'));
$query->bindParam(':products', $rowPay['product']);
$query->exe();}}

Inserting data into multiple tables not functioning correctly

I have the following two tables
Table player:
player_id (int)(primary)
player_name (varchar)
player_report_count (int)
Table report:
report_id (int)(primary)
player_id
report_description
report_location
Firstly I ask the user for the player_name and insert it into the player database. From here the player is given an id.
Then I tried to grab the value of the players report count and increment the current value by one (which isn't working).
This is followed by grabbing the playerId from the player table and then inserting into the corresponding column from the report table (also does not work).
When I insert some values into the database, the names, description and report are added to the database however the playerID remains at 0 for all entries and the player_report_count remains at a consistent 0.
What is the correct way to make these two features function? And also is there a more efficient way of doing this?
<?php
$records = array();
if(!empty($_POST)){
if(isset($_POST['player_name'],
$_POST['report_description'],
$_POST['report_location'])){
$player_name = trim($_POST['player_name']);
$report_description = trim($_POST['report_description']);
$report_location = trim($_POST['report_location']);
if(!empty($player_name) && !empty($report_description) && !empty($report_location)){
$insertPlayer = $db->prepare("
INSERT INTO player (player_name)
VALUES (?)
");
$insertPlayer->bind_param('s', $player_name);
$reportCount = $db->query("
UPDATE player
SET player_report_count = player_report_count + 1
WHERE
player_name = $player_name
");
$getPlayerId = $db->query("
SELECT player_id
FROM player
WHERE player_name = $player_name
");
$insertReport = $db->prepare("
INSERT INTO report (player_id, report_description, report_location)
VALUES (?, ?, ?)
");
$insertReport->bind_param('iss', $getPlayerId, $report_description, $report_location);
if($insertPlayer->execute()
&& $insertReport->execute()
){
header('Location: insert.php');
die();
}
}
}
Main issue here is you are getting player details before inserting it. $getPlayerId will return empty result always.
Please follow the order as follows.
Insert player details in to player table and get payerid with mysql_insert_id. After binding you need to execute to insert details to the table.
Then bind and execute insert report .
Then update the player table by incrementing report count with playerid which you got in step 1.
Note : use transactions when inserting multiple table. This will help you to rollback if any insert fails.
MySQL Query will return result object. Refer it from here https://stackoverflow.com/a/13791544/3045153
I hope it will help you
If you need to catch the ID of the last insterted player, This is the function you need if you're using PDO or if it's a custom Mysql Class, you need the return value of mysql_insert_id() (or mysqli_insert_id()) and then directly use it in the next INSERT INTO statement

Moving records to a new table updating original id accordingly

I need to create a new table with certain data from another table but update the original table with the ID of the newly inserted record from the new table. Like so:
NEW_TABLE
----------------
id
-- other data --
ORIGINAL_TABLE
----------------
id
new_table_id
-- other data --
However, the added records to new_table will be grouped to get rid of duplicates. So, it won't be a 1-to-1 insert. The query needs to update matching records, not just the copied record.
Can I do this in one query? I've tried doing a separate UPDATE on original_table but it's not working.
Any suggestions?
You are going to be doing 3 seperate queries as I see it.
$db = new PDO("...");
$stmt = $db->prepare("SELECT * FROM table");
$stmt->execute();
$results = $stmt->fetchAll();just iterate o
foreach ($results as $result) {
$stmt = "INSERT INTO new_table (...) VALUES (...)";
$stmt = $pdo->prepare($stmt);
$data = $stmt->execute();
$insert_id = $pdo->lastInsertId();
// Update first table
$stmt = "UPDATE table SET id=:last WHERE id=:id";
$stmt = $pdo->prepare($stmt);
$data = $stmt->execute(array('last' => $insert_id, 'id' => $result['id']));
}
The above is a global example of your workflow.
You can use temporary tables or create a view for NEW_TABLE.
Temporary Tables
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current session, and is dropped automatically when the session is closed. This means that two different sessions can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.) To create temporary tables, you must have the CREATE TEMPORARY TABLES privilege.
--Temporary Table
create temporary table NEW_TABLE as (select * from ORIGINAL_TABLE group by id);
Views
Views (including updatable views) are available in MySQL Server 5.0. Views are stored queries that when invoked produce a result set. A view acts as a virtual table. Views are available in binary releases from 5.0.1 and up.
--View
create view NEW_TABLE as select * from ORIGINAL_TABLE group by id;
The view will always be updated with the values in ORIGINAL_TABLE and you will not have to worry about having duplicate information in your database.
If you do not want to use the view, I believe you can only perform an insert on one table at a time unless you have some sort of view that would allow you to do both, but you probably want to do it as two steps in a transaction
First you will have to tell the database that you want to start a transaction. Then you will perform your operations and check to see if they were successful. You can get the id of last inserted row (this assumes you have an auto_increment field) to use in the second statement. If both statement seem to work fine, you can commit the changes, or if not, rollback the changes.
Example:
//Assume it will be okay
$success = true;
//Start the transaction (assuming you have a database handle)
$dbh->beginTransaction();
//First Query
$stmt = "Insert into ....";
$sth = $dbh->prepare($stmt);
//See if it works
if (!$sth->execute())
$success = false;
$last_id = $dbh->lastInsertId();
//Second Query
$stmt = "Insert into .... (:ID ....)";
$sth = $dbh->prepare($stmt);
$sth->bindValue(":ID", $last_id);
//See if it works
if (!$sth->execute())
$success = false;
//If all is good, commit, otherwise, rollback
if ($success)
$dbh->commit();
else
$dbh->rollBack();

How do I get all the ids of the row created by one multiple row insert statement

I'm new to php. So, please forgive me if this seems like a dumb question.
Say i have a MySQL insert statement insert into table (a,b) values (1,2),(3,4),(5,6). table 'table' has a auto increment field called 'id'.
how can I retrieve all the ids created by the insert statement above?
It will be great if i get an example that uses mysqli.
You can't. I would suggest that you maintain your own ids (using guid or your own auto-increment table) and use it when you insert into the table.
But it's possible to get the auto-increment value for the last inserted using LAST_INSERT_ID():
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
AngeDeLaMort's answer is almost right. Certainly, the most appropriate way to deal with the problem is to insert one row at a time and poll the insert_id or generate the sequence elsewhere (which has additional benefits in terms of scalability).
I'd advise strongly against trying to determine the last insert_id and comparing this the most recent insert_id after the insert - there's just too may ways this will fail.
But...an alternative approach would be:
....
"INSERT INTO destn (id, data, other, trans_ref)
SELECT id, data, other, connection_id() FROM source";
....
"SELECT id FROM destn WHERE trans_ref=connection_id()";
....
"UPDATE destn SET trans_ref=NULL where trans_ref=connection_id()";
The second query will return the ids generated (note that this assumes that you use the same connection for all 3 queries). The third query is necessary because connection ids to go back into the pool when you disconnect (i.e. are reused).
C.
In some cases, if you have another identifier of sort such as a UserID, you could filter your query by UniqueID's greater than or equal to mysql_insert_id(), limit by the number of affected rows and only display those by the user. This would really only work inside of a transaction.
$SQL = "INSERT INTO Table
(UserID, Data)
VALUES
(1,'Foo'),
(1,'Bar'),
(1,'FooBar')";
$Result = mysql_query($SQL);
$LastID = mysql_insert_id();
$RowsAffected = mysql_affected_rows();
$IDSQL = "SELECT RecordID
FROM Table
WHERE UserID = 1
AND RecordID >= '$LastID'
LIMIT '$RowsAffected'";
$IDResult = mysql_query($IDSQL);
as a follow up to AngeDeLaMort:
You could seperate your inserts and do it something like this:
$data = array (
array(1,2),
array(3,4),
array(5,6)
);
$ids = array();
foreach ($data as $item) {
$sql = 'insert into table (a,b) values ('.$item[0].','.$item[1].')';
mysql_query ($sql);
$id[] = mysql_insert_id();
}
Now all your new id's are in the $id array.
Maybe I can do this
$insert = "insert into table (a,b) values (1,2),(3,4),(5,6)";
$mysqli->query($insert);
$rows_to_be_inserted=3;
$inserted_id = $mysqli->insert_id // gives me the id of the first row in my list
$last_row_id = ($inserted_id+$rows_to_be_inserted)-1;
$mysql->query("select * from table where id between $inserted_id and $last_row_id");
what to you guys say?

Categories