MySQL - automatically update all references to specific table to use on delete cascade? I have a specific table for one of my software packages on a MySQL 5.1 box which I need to drop a few hundred entries. These are user names with names in uppercase, the application is case specific and expects lower. This table is referenced by a ton of other tables however, some of which may have references back to these users. 

Is there a ready way to adjust the foreign keys for all tables in my database which reference a given column 'username' in table 'logins' to have the on delete cascade attribute set? I don't see a ready way of doing so.  

What I need is to change all the other tables with foreign keys depending on this table to utilize an on delete cascade. I'm hoping to do so without manually changing a hundred tables. 

The select I'm utilizing is 

delete from user where user_name REGEXP '^.*[A-Z].+$';


The issue is that the application has created duplicate user IDs in the user_id field. I only want to retain the ID number for properly created usernames. 

The select above targets exactly what I want to get rid of. I don't have access to the application source which created these entries.
WARNING !!!
Before you do anything, mysqldump the entire database or tarball /var/lib/mysql
If you are concerned about case sensitivity, you need to hunt down the usernames in a special way
I tried this little experiment
use test
DROP TABLE rolando;
CREATE TABLE rolando
(id int not null auto_increment,
name varchar(20),primary key (id));
INSERT INTO rolando (name) VALUES
('rolando'),('Rolando'),
('ROLANDO'),('ROLANDO'),
('rolando'),('rolando');

I loaded the sample data
mysql&gt; use test
Database changed
mysql&gt; DROP TABLE rolando;
Query OK, 0 rows affected (0.03 sec)

mysql&gt; CREATE TABLE rolando
    -&gt; (id int not null auto_increment,
    -&gt; name varchar(20),primary key (id));
Query OK, 0 rows affected (0.07 sec)

mysql&gt; INSERT INTO rolando (name) VALUES
    -&gt; ('rolando'),('Rolando'),
    -&gt; ('ROLANDO'),('ROLANDO'),
    -&gt; ('rolando'),('rolando');
Query OK, 6 rows affected (0.08 sec)
Records: 6  Duplicates: 0  Warnings: 0

I ran these queries (please note subtle differences)
mysql&gt; SELECT name,COUNT(1) FROM rolando GROUP BY name;
+---------+----------+
| name    | COUNT(1) |
+---------+----------+
| rolando |        6 |
+---------+----------+
1 row in set (0.00 sec)

mysql&gt; SELECT name,MD5(name),COUNT(1) FROM rolando GROUP BY name,MD5(name);
+---------+----------------------------------+----------+
| name    | MD5(name)                        | COUNT(1) |
+---------+----------------------------------+----------+
| ROLANDO | b3f7ba680fe83ab0b5174737e8d536a2 |        2 |
| Rolando | e0732d78dc135b8fcc33ec79bfa89d1f |        1 |
| rolando | e80d4ab77eb18a4ca350157fd487d7e2 |        3 |
+---------+----------------------------------+----------+
3 rows in set (0.00 sec)

mysql&gt; SELECT name,MD5(name)=MD5(LOWER(name)) from rolando;
+---------+----------------------------+
| name    | MD5(name)=MD5(LOWER(name)) |
+---------+----------------------------+
| rolando |                          1 |
| Rolando |                          0 |
| ROLANDO |                          0 |
| ROLANDO |                          0 |
| rolando |                          1 |
| rolando |                          1 |
+---------+----------------------------+
6 rows in set (0.00 sec)

mysql&gt; SELECT name,COUNT(1) FROM rolando GROUP BY name;
+---------+----------+
| name    | COUNT(1) |
+---------+----------+
| rolando |        6 |
+---------+----------+
1 row in set (0.00 sec)

mysql&gt; SELECT name,(name LIKE lower(name)) like1,
    -&gt; (name = binary LOWER(name)) like2 FROM rolando;
+---------+-------+-------+
| name    | like1 | like2 |
+---------+-------+-------+
| rolando |     1 |     1 |
| Rolando |     1 |     0 |
| ROLANDO |     1 |     0 |
| ROLANDO |     1 |     0 |
| rolando |     1 |     1 |
| rolando |     1 |     1 |
+---------+-------+-------+
6 rows in set (0.00 sec)

mysql&gt;

Give this view of my experiment, a username with all uppercase or mixed case can be equal to an all lowercase UNLESS YOU USE BINARY operator with the comparison
I do not think BINARY can be applied to ON DELETE CASCADE.
However, you could something like this: To delete all usernames that are lowercase only, try running one of the following:
DELETE FROM logins WHERE username = BINARY LOWER(username);

or
DELETE FROM logins WHERE MD5(username) = MD5(LOWER(username));

If you run this now, you might nix all usernames in the other tables. Run this instead
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM logins WHERE username = BINARY LOWER(username);

or
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM logins WHERE MD5(username) = MD5(LOWER(username));

You will have to go to all tables that have a username in it and execute
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM &lt;whatevertable1&gt; WHERE user_name = BINARY LOWER(user_name) AND user_name REGEXP '^.*[A-Z].+$';
DELETE FROM &lt;whatevertable2&gt; WHERE user_name = BINARY LOWER(user_name) AND user_name REGEXP '^.*[A-Z].+$';
DELETE FROM &lt;whatevertable3&gt; WHERE user_name = BINARY LOWER(user_name) AND user_name REGEXP '^.*[A-Z].+$';
.
.
.
DELETE FROM &lt;whatevertableN&gt; WHERE user_name = BINARY LOWER(user_name) AND user_name REGEXP '^.*[A-Z].+$';

Since you have a ton of other tables, use the INFORMATION_SCHEMA to script it for you:
DELETE_SQLFILE=/root/SensitiveDelete.sql
MYSQL_CONN=&quot;-uroot -ppassword&quot;
echo &quot;SET FOREIGN_KEY_CHECKS=0;&quot; &gt; ${DELETE_SQLFILE}
mysql ${MYSQL_CONN} -ANe&quot;SELECT CONCAT('DELETE FROM ',table_schema,'.',table_name,' WHERE user_name = BINARY LOWER(user_name) AND user_name REGEXP ''\^.*[A-Z].+$''\) FROM information_schema.columns WHERE column_name='user_name'&quot; &gt;&gt; ${DELETE_SQLFILE}
cat ${DELETE_SQLFILE}

If the file is correct to you, run it in the mysql client like this
mysql ${MYSQL_CONN} -A &lt; ${DELETE_SQLFILE}

Give it a Try !!!