I am not sure how often you would stumble upon this problem, however, I did recently, and after some research, found a nifty way to overcome it.
Here is the scenario:
- You want to import a large CSV file into a database table.
- The files have potential to be very large, therefore you do not want to get rid of the old data before you have imported the new data successfully into a temporary table.
How do you do this?
- You import your data into a temporary table, let’s call it `tempdata`. This will take some time with large files, especially if you are processing each line before inserting.
- Once the import is successful, you simply clear the `realdata` table, and copy from the `tempdata` to the `realdata` table by doing a simple query:
INSERT INTO `realdata` SELECT * FROM `tempdata`. While this would work when there are no keys defined, you run into problems when you have UNIQUE or PRIMARY keys defined, because the key columns in the `tempdata` and `realdata` tables will overlap.
Oops. Now what?
You have two possible solutions:
- Select only the columns that you want to import from `tempdata` and import into the same columns into `realdata`, or
- You can be a little adventurous if you do not know beforehand what all the column names are (for example when you create tables on the fly).
Here is how you bring the adventure into your SQL mission:
First, you need to get the columns from the `realdata` table from the INFORMATION SCHEMA table:
SELECT `column_name` FROM information_schema.columns WHERE `table_name` = '" . $table_from . "' and column_name != 'id'
Now, this is assuming that your primary key or unique key’s name is “id”.
The result of this query will then contain all the columns in the `realdata` table except the ID column.
Now, with some PHP magic, you build up your query using these names and some string concatenation, and you can simply do this:
INSERT INTO `realdata` (**COLSTRING**) SELECT **COLSTRING** FROM `tempdata`