473,408 Members | 1,754 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Copying a MySQL row to another table

What's the easiest way to copy a row from one table to another
(with the same schema), without knowing in advance the number and
types of the columns?

The problem: I have several sets of tables with a primary key of
'account', which contains an email address. If someone changes
their email address, I need to change the 'account' field.
Unfortunately, someone thought it would speed up lookups if instead
of having one table 'settings', they have 27 tables: settings_a,
settings_b, settings_c, ... settings_z, settings_other, based on
the first letter of 'account'. I can't change this, at least not
right away, as there is a lot of code in a commercial distribution
we bought that uses it. The suggestion to use an account number
generated by an autoincrement column as a primary key instead of a
string is also something I can't implement right away.

So, to rename an account, I need to fetch the row (using the old
value of account), change the 'account' field, and likely (if the
first character changes) move the row to a different table and
delete it from the original one.

I don't know how many fields the table has besides 'account', or
what types they are, and my code needs to keep working if someone
adds, deletes, reorders, etc. columns. (All 27 tables in a set
will keep the same schema, and 'account' won't change.) Any ideas
how to construct an appropriate INSERT query? I'm not enthusiastic
about having to parse the output of 'SHOW CREATE TABLE settings_a',
especially trying to predict the output of SHOW CREATE TABLE for
the next couple of major versions of MySQL before they are started.

Gordon L. Burditt
Jul 23 '05 #1
4 18668
Gordon Burditt wrote:
What's the easiest way to copy a row from one table to another
(with the same schema), without knowing in advance the number and
types of the columns?

The problem: I have several sets of tables with a primary key of
'account', which contains an email address. If someone changes
their email address, I need to change the 'account' field.
Unfortunately, someone thought it would speed up lookups if instead
of having one table 'settings', they have 27 tables: settings_a,
settings_b, settings_c, ... settings_z, settings_other, based on
the first letter of 'account'. I can't change this, at least not
right away, as there is a lot of code in a commercial distribution
we bought that uses it. The suggestion to use an account number
generated by an autoincrement column as a primary key instead of a
string is also something I can't implement right away.

So, to rename an account, I need to fetch the row (using the old
value of account), change the 'account' field, and likely (if the
first character changes) move the row to a different table and
delete it from the original one.

I don't know how many fields the table has besides 'account', or
what types they are, and my code needs to keep working if someone
adds, deletes, reorders, etc. columns. (All 27 tables in a set
will keep the same schema, and 'account' won't change.) Any ideas
how to construct an appropriate INSERT query? I'm not enthusiastic
about having to parse the output of 'SHOW CREATE TABLE settings_a',
especially trying to predict the output of SHOW CREATE TABLE for
the next couple of major versions of MySQL before they are started.

Gordon L. Burditt

Gordon,

You should use an UPDATE not an INSERT to do this. This will
work even if account is the primary key. You should write a set
of SQL statements (one per table) like so:

UPDATE <table-name> SET account = <new_value> WHERE account =
<old-value>;

Since this is something you will probably have to periodically
create an executable with one UPDATE per table that accepts
new-value and old-value as parameters.

HTH
Jerry

Jul 23 '05 #2
Gordon Burditt wrote:
The problem: I have several sets of tables with a primary key of
'account', which contains an email address. If someone changes
their email address, I need to change the 'account' field.
Unfortunately, someone thought it would speed up lookups if instead
of having one table 'settings', they have 27 tables: settings_a,
settings_b, settings_c, ... settings_z, settings_other, based on
the first letter of 'account'.
Ouch. There are so many things wrong with this schema that I won't even
start. But I'm sure you already know that. Sorry you got mixed up with
such a botched project.
So, to rename an account, I need to fetch the row (using the old
value of account), change the 'account' field, and likely (if the
first character changes) move the row to a different table and
delete it from the original one.
My suggestion is to do the following three steps when you need to change
an account name:

1. Use UPDATE to change the account name in settings_a, even if though
changes the first letter so the account doesn't belong in that table
anymore.

UPDATE settings_a SET account = 'bishop' WHERE account = 'ash';

2. Copy the record to the correct table, according to the first letter.
Use INSERT without specifying the columns, and SELECT * without
specifying the columns. If the number, type, and order of the columns
in both tables match, it _should_ work.

INSERT INTO settings_b
SELECT * FROM settings_a WHERE account = 'bishop';

3. Remove the old record from the old table.

DELETE FROM settings_a WHERE account = 'bishop';
I don't know how many fields the table has besides 'account', or
what types they are, and my code needs to keep working if someone
adds, deletes, reorders, etc. columns. (All 27 tables in a set
will keep the same schema, and 'account' won't change.)
So other people have freedom to alter the schema, and expect the
applications magically to stay up to date, but not you? That hardly
seems fair.

For what it's worth, some database programming interfaces will allow you
to simply do a "SELECT * from table WHERE pk = value" and it'll return a
result set with enough metadata so you can know the field names and
types, and maybe the column order as well.
I'm not enthusiastic
about having to parse the output of 'SHOW CREATE TABLE settings_a',
especially trying to predict the output of SHOW CREATE TABLE for
the next couple of major versions of MySQL before they are started.


I wouldn't worry about that. It's the least of the problems in this
application!

Regards,
Bill K.
Jul 23 '05 #3
>> The problem: I have several sets of tables with a primary key of
'account', which contains an email address. If someone changes
their email address, I need to change the 'account' field.
Unfortunately, someone thought it would speed up lookups if instead
of having one table 'settings', they have 27 tables: settings_a,
settings_b, settings_c, ... settings_z, settings_other, based on
the first letter of 'account'.
Ouch. There are so many things wrong with this schema that I won't even
start. But I'm sure you already know that. Sorry you got mixed up with
such a botched project.


Fortunately, all I have to do is provision the webmail accounts,
and it provides scripts to do most of it. The webmail itself tracks
all the user-settable configuration stuff. The billing system
doesn't CARE about the spam filter settings (we don't charge extra
for spam filtering) so most of it can be ignored. But if a user
changes username, we want his settings to follow him. And there's
a lot of settings.

It wouldn't surprise me if we ran some benchmarks that those 270
tables instead of 10 *slow down* things overall, especially with
all the file opens.
So, to rename an account, I need to fetch the row (using the old
value of account), change the 'account' field, and likely (if the
first character changes) move the row to a different table and
delete it from the original one.


My suggestion is to do the following three steps when you need to change
an account name:

1. Use UPDATE to change the account name in settings_a, even if though
changes the first letter so the account doesn't belong in that table
anymore.

UPDATE settings_a SET account = 'bishop' WHERE account = 'ash';

2. Copy the record to the correct table, according to the first letter.
Use INSERT without specifying the columns, and SELECT * without
specifying the columns. If the number, type, and order of the columns
in both tables match, it _should_ work.

INSERT INTO settings_b
SELECT * FROM settings_a WHERE account = 'bishop';

3. Remove the old record from the old table.

DELETE FROM settings_a WHERE account = 'bishop';


This will work nicely. And when done in a transaction, it won't
risk leaving dregs around.
I don't know how many fields the table has besides 'account', or
what types they are, and my code needs to keep working if someone
adds, deletes, reorders, etc. columns. (All 27 tables in a set
will keep the same schema, and 'account' won't change.)


So other people have freedom to alter the schema, and expect the
applications magically to stay up to date, but not you? That hardly
seems fair.


I don't want provisioning breaking because of local changes or a
new version from the vendor. Or at least not often. We do want
to track the vendor since they are coming up with some useful stuff
at far less cost than we could. I might (or might not) be the one
making some of the other changes, but if it requires synchronized
changes in provisioning and the application, it gets a lot harder
to test.

I try to write SQL to be insensitive to added fields, or the
ordering of fields. That means NO "select * from", specifically
named fields on an insert, and such. Your suggestion above follows
the spirit while breaking the letter of those rules.
For what it's worth, some database programming interfaces will allow you
to simply do a "SELECT * from table WHERE pk = value" and it'll return a
result set with enough metadata so you can know the field names and
types, and maybe the column order as well.


I thought about building up an insert query using that information.
It's a lot of trouble.
I'm not enthusiastic
about having to parse the output of 'SHOW CREATE TABLE settings_a',
especially trying to predict the output of SHOW CREATE TABLE for
the next couple of major versions of MySQL before they are started.


I wouldn't worry about that. It's the least of the problems in this
application!


Well, I really don't want my parser to choke just because MySQL 5.7
adds a table attribute "DEFAULT TIMEZONE", totally irrelevant to
any features I'm actually using, but making it difficult to upgrade
the server. I don't like running really ancient versions of SQL
servers and I don't want to intentionally write in something that
will make it harder. Most of the older provisioning system doesn't
even use sub-selects because the servers it used didn't support
them.

Gordon L. Burditt
Jul 23 '05 #4
Gordon Burditt wrote:
It wouldn't surprise me if we ran some benchmarks that those 270
tables instead of 10 *slow down* things overall, especially with
all the file opens.
Well, it *certainly* slows down the code development and maintenance.
But I bet you're right about runtime performance as well.
This will work nicely. And when done in a transaction, it won't
risk leaving dregs around.
You may already know this, but using transactions depends on the tables
being stored in InnoDB format. The MyISAM storage engine doesn't
provide transaction isolation features.

If you are using InnoDB, at least that would mitigate the concern above
of having many open files. The default configuration for InnoDB is that
all the tables share the same physical database file.
Well, I really don't want my parser to choke just because MySQL 5.7
adds a table attribute "DEFAULT TIMEZONE", totally irrelevant to
any features I'm actually using, but making it difficult to upgrade
the server.


That's very honorable of you. But I assume other bad design decisions
exist in the database, which are more likely to prevent a smooth upgrade
to some hypothetical future major release of MySQL.

Good luck,
Bill K.
Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: bobb | last post by:
(I'm a long term newbie :) ) I wanted to copy a blob's contents in mysql in python from one record to another. I had a heck of a time with it, so I wanted to post it for others. The where clause...
0
by: Bennett Haselton | last post by:
I'm trying to port my MySQL tables for a database called "tracerlock" from one server to another. On the old server, in the /var/lib/mysql/tracerlock directory, there was a ".MYD", ".MYI" and...
0
by: Ville Mattila | last post by:
Hi everyone, Is there any easy way to duplicate a row in a table with auto increment column, that shouldn't of course be copied. I tried a query "NSERT INTO table SELECT * FROM table" but it...
0
by: Terry | last post by:
I am trying to move a datbase from one machine to another. I have tried two different methods and neither are working. First I tried using : >> mysqldump dbName > backup_file.sql >> mysql...
0
by: Mike Chirico | last post by:
Interesting Things to Know about MySQL Mike Chirico (mchirico@users.sourceforge.net) Copyright (GPU Free Documentation License) 2004 Last Updated: Mon Jun 7 10:37:28 EDT 2004 The latest...
1
by: usaims | last post by:
I'm learning how to copy columns and I'm having a little trouble. The column that I'm trying to copy is from the same database. Correct me if I am wrong, but I think you have to create the column...
0
by: TB | last post by:
Hi All: This news group is proving to be great help on my path towards mastering ASP.NET thanks to all of you helpful souls out there. I am looking forward to the day when I can contribute with...
5
by: TB | last post by:
Hi All: This news group is proving to be great help on my path towards mastering ASP.NET thanks to all of you helpful souls out there. I am looking forward to the day when I can contribute...
4
by: zMisc | last post by:
Is it possible to copy a table from one schema to another schema by just copying the frm file to the directory for the new schema? What is the best way to create a new database with all the...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.