Issue in copying rows from one table to another - php

I am implementing a request mechanism where the user have to approve a request. For that i have implemented a temporary table and main table. Initially when the request is added the data will be inserted to the temporary table, on approval it will be copied to the main table.
The issue is there will be more than 5k rows to be moved to the main table after approval + another 3-5 row for each row in the detail table (stores the details).
My current implementation is like this
//Get the rows from temporary table (batch_temp)
//Loop through the data
//Insert the data to the main table (batch_main) and return the id
//Get the details row from the temporary detail table (batch_temp_detail) using detail_tempid
//Loop through the data
//Insert the details to the detail table (batch_main_detail) with the main table id amount_id
//End Loop
//End Loop
But this implementation would take atleast 20k queries. Is there any better ways to implement the same.
I tried to create a sqlfiddle but was unable to create one. So i have pasted the query in pgsql.privatepaste.com

I'm sorry that I'm not familiar with PostgreSQL. My solution is in MySQL, I hope it can help since if they (MySQL & PostgreSQL) are same.
First, we should add 1 more field into your batch_main table to track the origin batch_temp record for each batch_main record.
ALTER TABLE `batch_main`
ADD COLUMN tempid bigint;
Then, on approval, we will insert 5k rows by 1 query:
INSERT INTO batch_main
(batchid, userid, amount, tempid)
SELECT batchid, userid, amount, amount_id FROM batch_temp;
So, with each new batch_main record we have its origin batch_temp record's id. Then, insert the detail records
INSERT INTO `batch_main_detail`
(detail_amount, detail_mainid)
SELECT
btd.detail_amount, bm.amount_id
FROM
batch_temp_detail `btd`
INNER JOIN batch_main `bm` ON btd.detail_tempid = bm.tempid
Done!
P/S:
I'm confuse a bit about the way you name your fields, and since I do not know about PostgreSQL and by looking into your syntax, can you use same sequence for primary key of both table batch_temp & batch_main? If you can, it's no need to add 1 more field.
Hope this help,

Simply need to update your Schema. Instead of having two tables: one main and one temporary, you should have all the data in main table, but have a flag which indicates whether a certain record is approved or no. Initially it will be set to false, and once approved it will simply be set to true and then the data can display on your website etc. That way you will not need to write the data two times, or even have to move it from one table to another

You haven't specified RDBMS you are using, but good old INSERT with SELECT in it must do the trick in one command:
insert main (field1,...,fieldN) select field1,...,fieldN from temporary

Related

Merging Two Databases - How to Skip Same ID or Generate New ID

I have two MySQL databases. I would like to data from one database to another. Both have the same structure and entries except that one database has same IDs for different items within the same tables. I don't want to replace the data from the old to the new database. If IDs are there, I would like the new database to skip it. If it's a duplication, I would like a new ID to be generated.
I'd like to use phpmyadmin for this but have no idea if this is even possible.
0.) Make backup of both tables
PHPMYADMIN will be sufficient for your request.
First you need to ensure there is no duplicating id's or primary keys.
Assuming two tables testtable1 and testtable2 have columns testtable_id, name
1.) firstly you would make query on second table
UPDATE testtable2 SET testtable2.testtable_id = testtable2.testtable_id + (SELECT MAX( testtable1.testtable_id ) FROM testtable1);
2.) Than, again in testtable2, there is tool Copy table to (database.table): under Operations menu, set DB name and testtable1 name (db name should be already set), select Data only radio button option and click Go. 3.) Now, you have all data from both tables in testtable1.
Edit. Firstly I thought it is matter of two tables in same database. But nevertheless you can use step two for rest of the tables too. Just set correct DB and table name in step two. Also, before that, set query so expecting ID to be higher than MAX ID of table you want to extend. You can hard code parenthesis part with exact number of MAX ID first DB corresponding table.

How to duplicate specific table content(given condition) into a new database table using php codeigniter

How to duplicate specific table content(given condition) into a new database table using php codeigniter ?
For example, I should get from db job table the following:
job_id, job_title, job_description, client_id provided that the job was already awarded by client to provider (i.e. "status"=="Awarded")
NOTE: I should be able to completely "copy/duplicate" these entries to avoid missing link if ever the specific job was later on deleted by client
provider_id , proposal_id from db job_proposal table (again, I think condition here is status==approved)
and then add NEW fields that are nowhere in the existing tables in my db..
I would appreciate any help.. thanks!
CREATE TABLE 'new_table_name' LIKE 'your_table_name';
Then
INSERT INTO New_table SELECT * FROM Old_table1,Old_table2 GROUP BY ID;
This will create a new table with all the datas.This command is used as a backup for the tables.
NOTE: If the second table doesn't have the same strucutre, u hv to first create the necessary columns, and then get the backup of the datas from the second table

MySQL: How to get changes of last UPDATE

I am working on a database application with MySQL and PHP. At this moment I'm trying to get the changes caused by the last UPDATE. My first way to solve the problem is
getting the 'old' state with SELECT
Doing the changes with UPDATE
getting the 'new' state with SELECT
comparing the arrays with php
These are three mysql-connections...
Is there any way to shorten this?
You could do an before update trigger that will push an entire copy of the record to a history table that also contains additional state data you wish to store (updated date, user etc.)
This way you will have a complete revision history of what happened with what records and it should happen transparently. only think to remember is you should drop any unique constraints from the history table.
Hope this helps.
you can use the following hack using variables:
update table set
col=(#oldValue:=col),col=newValue
where id=1234;
select #oldValue;
Let me tell you how I do that,
When I update a row, firstly I get which row I'm updating and I call them active records. Then I compare each column of active records with the form fields. That's how I know which column has changed.
And if you want to store changed columns, create history table that would be like;
id (for primary key)
tablename (which table i'm updating)
recordid (which row i'm updating)
column (which columns has been changed)
oldvalue (active record value)
newvalue (form value-updated value)
date (obvious)
user (who did this change)
After that, you can use your imagination for structures how you want to use.

Inserting an entry in multiple tables in an sql database

I'm creating a game in actionscript that requires the use of an external database to store user details and scores.
This database will contain multiple tables, currently there are two.
My first table contains the headers - ID, email, username, password.
My second table contains the headers - ID, lvl1Score, lvl2Score, lvl3Score.
In my game, when a new user is created it creates an entry in the first table with the ID auto-incrementing.
My question is - Is there anyway to automatically create an entry in my second table with its default values and the same ID when I add to my first table?
I've read about joins, but everything i've read just talks about looking up data over multiple tables.
Also, is my table structure correct in the sence that the ID value can be used using the JOIN keywork to look up an entry from both tables.
I would suggest you to go for triggers.
create or replace trigger trigger_name after
insert on table1
for each row
begin
insert into table2 values(new.id,"value for lvl2score","value for lvl3score");
end
Something like this.
If the tables truly have a one-to-one relation, I would recommend that you simply make one table having all the fields.
Or did you mean this should store multiple scores for each individual user? In this case, you should not insert a default record for the user. Instead, the score.ID field should instead reference user.ID and allow duplicates.
I suggest you to use triggers and for more flexibility create a many-many relationship between "user" and "level", so you will end up with 3 tables:
user
level
user_level (this will contain the foreign keys: user_id, level_id)

splitting data into multiple tables

I am building a employees page.
Some of the information goes into an 'employees' table but some of it goes into a 'availability' table that is referenced to the 'employee' table:
availability:
id / employeeid (unique id from employees table) / monday available / and on and on /
So I don't have that unique ID from the employees table until I create them.
Is it fine to do a query where I set the employee info and then a query to get the last created row in the employee table and then use the unique id from that to set the availability...
Or is that messy and should I have a create employee page and THEN a set availability page?
So basically I want to know if it is cleaner and 'better' coding to separate the two functions?
Adding to #Quassnoi's answer:
You would add the employee record, then use the MySQL LAST_INSERT_ID() function to find the autoincremented unique id for the employee record you added. You can then feed that value back into the availability INSERT statement.
More details are on the MySQL manual page at http://dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html
It's important that you not use a SELECT statement (e.g. SELECT MAX(employee.id)) since there might be other uses adding records as well. LAST_INSERT_ID() is specific to your connection
Of course create employee first, availability then.
If your tables are InnoDB, you can do it in a transaction so that you can rollback the whole update if something goes wrong.
Is it fine to do a query where I set
the employee info and then a query to
get the last created row in the
employee table and then use the unique
id from that to set the
availability...
Yes, that sounds OK. If you use an autoincrement column for employeeid, you can then use mysql_insert_id() or equivalent to retrieve that last inserted id safely. Don't do SELECT MAX(employeeid) FROM ...., because you might get problems when loads of people are using it concurrently.
You can easily get the last insered record via
mysql_insert_id()
After that, you can insert an availability record for the desired employee.
Note: I would choose a framework that takes care of these issues, like Symfony or Cake.
Using the "last created row" may not always work the way that you're expecting and may complicate things in the future if there's growth or if another programmer assumes the project. If I understand what you're looking for, you should instead have 3 tables. One table for employees, one table for availability, and a third table should be used to store unique records for the association. In the association table each row will have columns for : a unique ID, the employee id, the availability id.

Categories