Inserting data to two tables at once in mysql - php

I have two mysql tables:
table1_id (PK) | table1_data
and
table2_id (PK) | table1_id (FK) | table2_data
and they both together have to be created at once to represent single object. Primary keys are auto incremented, so after inserting table1_data when I move on to creating table2, how can I get the correct, freshly created table1_id value to insert there?
I'm doing it in php:
$stmt = $conn->prepare("INSERT INTO table1 (`table1_data`) VALUES (:data)");
$stmt->bindParam(':data', $data);
$stmt->execute();
$stmt2 = $conn->prepare("INSERT INTO table2 (`table1_id`,`table2_data`) VALUES (:id,:data)");
$stmt2->bindParam(':id', $table1_id); //how can I get the id of row just created above by stmt?
$stmt2->bindParam(':data', $data2);
$stmt2->execute();

You can use the PDO::lastInsertId method for that. Call it after executing your first insert, so you get:
$stmt = $conn->prepare("INSERT INTO table1 (`table1_data`) VALUES (:data)");
$stmt->bindParam(':data', $data);
$stmt->execute();
$table1_id = $conn->lastInsertId();
You can then use $table1_id in your second query.

Related

How to check how many rows were updated and inserted in a ON DUPLICATE statement?

I have a statement that looks like this:
$count=0;
while($row = pg_fetch_assoc($result)){
$sql=("INSERT INTO joblist (job_no, billed, completed, paid, paid_amount, inv_no, invoice, type, o_submitted, approval_date, gals, jobtype, name, state, region, territory)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE
job_no=VALUES(job_no), billed=VALUES(billed),completed=VALUES(completed), paid=VALUES(paid), paid_amount=VALUES(paid_amount), inv_no=VALUES(inv_no), invoice=VALUES(invoice), type=VALUES(type), o_submitted=VALUES(o_submitted), approval_date=VALUES(approval_date), gals=VALUES(gals), jobtype=VALUES(jobtype), name=VALUES(name), state=VALUES(state), region=VALUES(region), territory=VALUES(territory)");
$stmt = $conn->prepare($sql);
$stmt->bind_param("ssssssssssssssss",$job_no, $billed, $completed, $paid, $paid_amount, $inv_no, $invoice, $type, $o_submitted, $approval_date, $gals, $jobtype, $name, $state, $region, $territory);
$stmt->execute();
$count++;
}
The problem is, I cannot decipher between updated rows and inserted rows. Is there a way I can do this?
I know i can use the effected rows function, but it reads the same if updated/inserted. Any ideas? thanks!
You're looking for an UPSERT with a RETURNING clause.
Taking into account the following table a records ..
CREATE TEMPORARY TABLE t
(id INT PRIMARY KEY, name TEXT);
INSERT INTO t VALUES (1,'elgar'),(2,'bach'),(3,'brahms');
.. you can use an UPSERT to catch a primary key conflict and ask the query to return the affected records. You can put this insert inside a CTE and count it with a new query. The following query will insert two already existing primary keys (1 and 2) and a new one (4):
WITH j (affected_rows) AS (
INSERT INTO t VALUES (1,'edward'),(2,'johann sebastian'),(4,'schubert')
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name
RETURNING *
) SELECT count(affected_rows) FROM j;
count
-------
3
See the results yourself :-)
SELECT * FROM t ORDER BY id;
id | name
----+------------------
1 | edward
2 | johann sebastian
3 | brahms
4 | telemann

Using PDO to look up records in one table and append data to another

I have 2 tables, each with 3 columns
Table1 has a columns, id, code and name
Table2 has a columns, id, name and table1id
When new records are created in Table2 the column table1id needs to be filled out with the id Table1 has for that name.
The query must look at the last id created in Table2 and match the Table2 name column with the name in Table1 and then append the id associated with the name to Table2.
How can this be done correctly? The following is the PDO structure I have:
$last_id = $conn->lastInsertId();
$stmt = $conn->prepare('UPDATE `Table2` SET `table1id` = :last_id_0) WHERE `id` = :last_id');
$stmt->execute([
]);
The variable :table1id should be based on the last created record in Table2 but I am unsure with how to continue from here.
This is a visual representation of the two tables described:
UPDATE:
Last inserted id is assigned to the variable $last_id like this:
$stmt = $conn->prepare( ' INSERT INTO `Table2` (`name`)
VALUES (:name ) ' );
$stmt->execute([
'name' => $_POST['name']
])
$last_id = $conn->lastInsertId();
I think I know what you want. I assume table1 has already existed for a long time, and all you do is insert a row into table2. You can use an INSERT INTO SELECT like this:
$stmt = $conn->prepare('INSERT INTO `Table2` (`name`, `table1id`)
SELECT `name`, `id`
FROM `table1`
WHERE `table1`.`name` = :name');
$stmt->execute(['name' => $_POST['name']]);
This query inserts a new row into table2 using the selected name and id from table1. The selected record in table1 is the one with the matching name.
Please note that this will only work if the names in table1 are unique.
if you need to change table2.table1id according to table1.name.
$last_id = $conn->lastInsertId();
$stmt = $conn->prepare('UPDATE Table2
INNER JOIN table1 ON Table1.name = Table2.name
SET Table2.table1id = :id
WHERE Table1.name = :name');
$stmt->execute(['id'=>$last_id , 'name' => $_POST['name']])
Why not to write a query which is just verbatim your requirement?
look up records in one table
$stmt = $conn->prepare('SELECT id from table1 where name=?');
$stmt->execute([$_POST['name']]);
$row = $stmt->fetch();
append data to another
$stmt = $conn->prepare('INSERT INTO `Table2` (`table1id`) VALUES (:t1id)');
$stmt->execute(['t1id' => $row['id']);
Note that it's a very bad idea to duplicate data in the tables, so it's best to keep the name only in table1. You can always have it for table2 using JOIN.

Query for insert one record (ID) from one table to another table

Please help me with mysql query...
i have this situation:
table 1 -- tasks
**id**|task_name|status|created_at|updated_at|user_id
and table 2 -- samples
id|sample_name|...|...|...many other things|**task_id**|user_id
i want that in table 2 in column "task_id" is "id" from table 1 or "tasks.id" ?
I have this query but it's result is number 1 in each column instead of the id of each entry..
INSERT INTO samples(task_id),
SELECT tasks.id from tasks
JOIN samples
ON task_id = tasks.id
thanks for help...
Assuming you are doing this through PHP (based on you tagging it) and assuming that you need an insert into both tables, the basic jist would be (also assuming the id field in tasks is auto-increment):
$stmt1 = $conn->prepare("INSERT INTO tasks (fields, other_fields) VALUES (?, ?)"))
{
$stmt1->bind_param("ss",$fields, $other_fields);
$stmt1->execute();
$lastid = $conn->insert_id;
$stmt1->close();
}
Now you can use the variable $lastid as the value when you insert the samples data.
$stmt2 = $conn->prepare("INSERT INTO samples (id, other_fields, task_id) VALUES (?, ?, /)"))
{
$stmt2->bind_param("isi",$ID, $other_fields, $lastid);
$stmt2->execute();
$stmt2->close();
}
If samples already exists and you need to update it with the id from tasks, you'd just update samples after the insert into tasks, assuming you have something to use in the where clause that can uniquely identify the record you want updated :
$stmt2 = $conn->prepare("UPDATE samples set task_id = ? where user_id - ?)
$stmt2->bind_param("ii",$lastid, $user_id);
$stmt2->execute();
$stmt2->close();
}
else {
die(mysqli_error($conn));
}
I'm making a lot of assumptions, I know. But I can't comment yet so this is my only way of assisting.
Unfortunately your method is not true and not logical.
At you at the moment of recording there is no field which could unite the data of the table, so you need to get the task_id first and then insert it into the query

if id exist use on duplicate key, else insert

I have a database with following table test_users:
| id | Username | Password |
| 1 | pat | ***** |
| 2 | roger | ***** |
| 3 | luke93 | ***** |
And to insert a new row I use following code, and it works fine:
$sql = $conn->prepare("INSERT INTO `test_users` (`Username`, `Password`) VALUES (?,?)");
$sql->bind_param('ss',$name, $email);
But now i am trying to make a "update profile"-page and I wanted to use ON DUPLICATE KEY. That means I need to check if idexists and if so update the row. Neither Username or Password is Unique, but id is. I have a $_SESSION["id"] which is available if the user is logged in. Can I use that in some way?
So how do I write a SQL-sentence that finds out if id exist, and if so, overwrite it with ON DUPLICATE KEY (or a better way)?
first write selct query and count num rows if its 0 then insert query fire else update query
UPDATE works the same as an insert. You just need to pass the WHERE condition.
You can do this with the following code, Try it
$id = $_SESSION['id'];
$sql = "UPDATE test_users SET Username=?, Password=? WHERE id=?";
$stmt = $conn->prepare($sql);
$stmt->bind_param($Username, $Password, $id);
$stmt->execute();
Assign unique key of your unique field and try below query
Insert into a MySQL table or update if exists
INSERT INTO test_user(id, username, password) VALUES(1, "test", "test") ON DUPLICATE KEY UPDATE
username="test", password="test"
Use INSERT ... ON DUPLICATE KEY UPDATE
QUERY:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name="A", age=19
credits to Donnie

PDO insert new record to database based on lastInsertId()

Ive just started learning PDO and I'm struggling by simply inserting a new record based from
$lastid = $db->lastInsertId();
The ID gets created in the database table from another function.
But nothing happens when i try to insert a new record based on that ID.
function add_name($last_id, $name) {
$db = some_db();
$query = "INSERT INTO team (name) VALUES (:name) WHERE id = '".$last_id."'";
$stmt = $db->prepare($query);
$stmt ->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->execute();
}
INSERT ... WHERE is not valid SQL. If you are inserting a new record, an autoincremnt ID will be generated at that time (if you have such defined for the table).
If you are trying to INSERT a new row into a related table with the last id from another table, then you would set that value as one of your column inputs. So the workflow would look like this:
INSERT [column data for table_a] INTO table_a
[GET autoincrement from last insert]
INSERT (table_a_foreign_key_column, [other table_b columns]) VALUES (table_a_id, [other table_b values) INTO table_b
UPDATE:
Since UPDATE is what you want, you can make update like this:
UPDATE team
SET name = :name
WHERE id = :id
You should use parameters for both name and id values. It is still not clear to me why you would need to make an insert and then an update within the same script execution. It's not like you received any more input from the user that you did not already have. I would guess you could just insert this name values when first creating the record and save yourself the extra trouble of multiple queries.
i think your sql query is wrong, try this:
function add_name($last_id, $name) {
$db = some_db();
$query = 'INSERT INTO team (id, name) VALUES (:id, :name)';
$stmt = $db->prepare($query);
$stmt ->bindParam(':name', $name, PDO::PARAM_STR);
$stmt ->bindParam(':id', $last_id, PDO::PARAM_INT);
$stmt->execute();
}
MySQL Insert Where query

Categories