Regex to get names of all SQL tables - mysql

I have a CREATE TABLE document and I need to get a listing of all the table names. This is what I have:
CREATE TABLE `mturk_reviewqueue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`catalog_id` int(11) DEFAULT NULL,
`tv_series_id` int(11) DEFAULT NULL,
`added_on` datetime NOT NULL,
`correct_url` varchar(100) DEFAULT NULL,
`notes` varchar(400) DEFAULT NULL,
`completed_on` datetime DEFAULT NULL,
`completed_by_id` int(11) DEFAULT NULL,
`top_url` varchar(100) DEFAULT NULL,
`diff_score` decimal(5,2) DEFAULT NULL,
`ip_checkout` varchar(24) DEFAULT NULL,
`incorrect_original_url` varchar(100) DEFAULT NULL,
`fix_notes` varchar(1000) DEFAULT NULL,
`is_promotional_content` tinyint(1) DEFAULT NULL,
`contains_multiple_titles` tinyint(1) DEFAULT NULL,
`is_garbage_series` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `completed_by` (`completed_by_id`),
KEY `catalog_id` (`catalog_id`),
KEY `tv_series_id` (`tv_series_id`),
CONSTRAINT `mturk_reviewqueue_ibfk_1` FOREIGN KEY (`completed_by_id`) REFERENCES `auth_user` (`id`),
CONSTRAINT `mturk_reviewqueue_ibfk_2` FOREIGN KEY (`catalog_id`) REFERENCES `main_catalog` (`id`),
CONSTRAINT `mturk_reviewqueue_ibfk_3` FOREIGN KEY (`tv_series_id`) REFERENCES `main_tvseriesinstance` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=196089 DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'mturk_worker'
CREATE TABLE `mturk_worker` (
`worker_id` varchar(22) NOT NULL DEFAULT '',
`notes` varchar(100) NOT NULL,
...etc...
And this is what I need:
mturk_reviewqueue
mturk_worker
etc...
So far I have:
r'CREATE\sTABLE\s`(.+)`\s\('
This is getting me the table name, but I can't seem to get rid of all the junk after the table name but before the next one. What would be the best regex to do this?

r'CREATE\sTABLE\s`(.+?)`'
This should do it for you.

If you'd like a command line option. Say your sql file is named "foo":
cat foo | grep 'CREATE TABLE' | cut -d\` -f2
This should work on MacOS.

This should also work (even when there should be more than one blank between words) ...
/CREATE\s+TABLE\s+`([^`]+)`/g

If you're using ack you can do this:
ack 'CREATE TABLE `(.+)`' --output='$1'

Related

MySQL: Optimizing JOINs to find non-matching records

We have a host management system (let's call it CMDB), and a DNS system, each using different tables. The former syncs to the latter, but manual changes cause them to get out of sync. I would like to craft a query to find aliases in CMDB that do NOT have a matching entry in DNS (either no entry, or the name/IP is different)
Because of the large size of the tables, and the need for this query to run frequently, optimizing the query is very important.
Here's what the tables look like:
cmdb_record: id, ipaddr
cmdb_alias: record_id, host_alias
dns_entry: name, ipaddr
cmdb_alias.record_id is a foreign key from cmdb_record.id, so that one IP address can have multiple aliases.
So far, here's what I've come up with:
SELECT cmdb_alias.host_alias, cmdb_record.ipaddr
FROM cmdb_record
INNER JOIN cmdb_alias ON cmdb_alias.record_id = cmdb_record.id
LEFT JOIN dns_entry
ON dns_entry.ipaddr = cmdb_record.ipaddr
AND dns_entry.name = cmdb_alias.host_alias
WHERE dns_entry.ipaddr IS NULL OR dns_entry.name IS NULL
This seems to work, but takes a very long time to run. Is there a better way to do this? Thanks!
EDIT: As requested, here are the SHOW CREATE TABLEs. There are lots of extra fields that aren't particularly relevant, but included for completeness.
Create Table: CREATE TABLE `cmdb_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ip_version` int(11) DEFAULT NULL,
`ipaddr` varchar(40) DEFAULT NULL,
`ipaddr_numeric` decimal(40,0) DEFAULT NULL,
`block_id` int(11) NOT NULL,
`record_commented` tinyint(1) NOT NULL,
`mod_time` datetime NOT NULL,
`deleted` tinyint(1) NOT NULL,
`deleted_date` datetime DEFAULT NULL,
`record_owner` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ipaddr` (`ipaddr`),
KEY `cmdb_record_fe30f0f7` (`ipaddr`),
KEY `cmdb_record_2b8b575` (`ipaddr_numeric`),
KEY `cmdb_record_45897ef2` (`block_id`),
CONSTRAINT `block_id_refs_id_ed6ed320` FOREIGN KEY (`block_id`) REFERENCES `cmdb_block` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=104427 DEFAULT CHARSET=latin1
Create Table: CREATE TABLE `cmdb_alias` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`host_alias` varchar(255) COLLATE latin1_general_cs NOT NULL,
`record_id` int(11) NOT NULL,
`record_order` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `cmdb_alias_fcffc3bb` (`record_id`),
KEY `alias_lookup` (`host_alias`),
CONSTRAINT `record_id_refs_id_8169fc71` FOREIGN KEY (`record_id`) REFERENCES `cmdb_record` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=155433 DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
Create Table: CREATE TABLE `dns_entry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rec_grp_id` varchar(40) NOT NULL,
`parent_id` int(11) NOT NULL,
`domain_id` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`type` varchar(6) DEFAULT NULL,
`ipaddr` varchar(255) DEFAULT NULL,
`ttl` int(11) DEFAULT NULL,
`prio` int(11) DEFAULT NULL,
`status` varchar(20) NOT NULL,
`op` varchar(20) NOT NULL,
`mod_time` datetime NOT NULL,
`whodunit` varchar(50) NOT NULL,
`comments` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `dns_entry_a2431ea` (`domain_id`),
KEY `dns_entry_52094d6e` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=49437 DEFAULT CHARSET=utf8
If you don't have one already, create an index on dns_entry(ipaddr, name). This might be all you need to speed the query.

Foreign key constraint fails during `drop table`

I have a strange problem in which I'm not able to delete a table as a foreign key constraint fails. The scenario is as follows.
I'm trying to drop the table departments from my DB, the structure for which is as follows:
show create table `departments`
CREATE TABLE `departments` (
`dept_id` int(11) NOT NULL AUTO_INCREMENT,
`dept_name` varchar(50) NOT NULL,
PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Now, the only other table in the database that has department_id is the employee table:
show create table employee
CREATE TABLE `employee` (
`emp_id` varchar(20) NOT NULL,
`role` varchar(10) DEFAULT NULL,
`password` varchar(500) DEFAULT NULL,
`division_id` int(20) DEFAULT NULL,
`email_bb` varchar(100) DEFAULT NULL,
`is_active` tinyint(1) NOT NULL,
`date_joining` date DEFAULT NULL,
`date_confirmation` date DEFAULT NULL,
`date_appraisal` date DEFAULT NULL,
`date_leaving` date DEFAULT NULL,
`first_name` varchar(100) DEFAULT NULL,
`middle_name` varchar(100) DEFAULT NULL,
`last_name` varchar(100) DEFAULT NULL,
`sex` varchar(1) DEFAULT NULL,
`dob` date DEFAULT NULL,
`email_other` varchar(100) DEFAULT NULL,
`contact` varchar(100) DEFAULT NULL,
`present_addr` varchar(1000) DEFAULT NULL,
`perma_addr` varchar(1000) DEFAULT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
As you can see, none of these tables are related via foreign keys. So why do I get this error when trying to drop the department table:
#1217 - Cannot delete or update a parent row: a foreign key constraint fails
Is there a better way (and hopefully, simpler) way to see the foreign keys defined? What might be going wrong?
show create table doesn't show incoming FK restraints (e.g. FK is specified in child table, not parent)
So there is a possibility that you have another table with a FK constraint to that table. I usually dump the schema of the database, which shows all FK constraints.

How to add foreign key in table using existing column, without losing data?

I have a table in which I need to add foreign key on an existing column. Following is create table:
CREATE TABLE `itemtx` (
`itemTxid` int(11) NOT NULL AUTO_INCREMENT,
`itemcode` varchar(1) NOT NULL,
`weight` decimal(7,3) DEFAULT NULL,
`txtype` varchar(10) DEFAULT 'Pickup',
`tripstopid` int(11) NOT NULL,
`barcode` varchar(25) DEFAULT NULL,
`bagcount` int(11) DEFAULT '1',
PRIMARY KEY (`itemTxid`)
) ENGINE=InnoDB AUTO_INCREMENT=33524 DEFAULT CHARSET=latin1
I need to add foreign key on tripstopid column. I cannot drop or empty table as it contains data. Following is the referenced table:
CREATE TABLE `tripstop` (
`tripstopid` int(11) NOT NULL AUTO_INCREMENT,
`tripid` int(11) DEFAULT NULL,
`locationName` varchar(100) DEFAULT NULL,
`userName` varchar(100) DEFAULT NULL,
`locationid` int(11) DEFAULT NULL,
`datetime` varchar(20) DEFAULT NULL,
`createts` varchar(20) DEFAULT NULL,
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`userid` int(11) DEFAULT NULL,
`tid` int(11) DEFAULT NULL,
PRIMARY KEY (`tripstopid`)
) ENGINE=InnoDB AUTO_INCREMENT=4691 DEFAULT CHARSET=latin1
How can I do this without losing my data?
You can achieve this by following:
ALTER TABLE itemtx
ADD FOREIGN KEY (tripstopid) REFERENCES tripstop(tripstopid);
Verified by creating tables, inserting data in them and then updating table for foreign key, previously entered data is not lost.

MySQL Error Number 150 when creating Table with Foreign Key

I am having an issue creating a new table in my database. I've seen that the error code it is returning is to do with Foreign Key constraints.
I checked to ensure that the data type of the foreign key in the new table matched the data type of the primary key in the other table. They are both int(11).
However I am still getting an error. Am I missing something? This is my SQL script for creating the new table:
CREATE TABLE `regular_features` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) DEFAULT NULL,
`day` VARCHAR(200) DEFAULT NULL,
`description` TEXT DEFAULT NULL,
`programme_id` INT(11) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`programme_id`) REFERENCES directoryprogramme(id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
This is the original table containing the primary key:
CREATE TABLE `directoryprogramme` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(250) NOT NULL,
`broadcast_time` VARCHAR(100) NOT NULL,
`description` TEXT NOT NULL,
`days` VARCHAR(150) NOT NULL,
`contributors` VARCHAR(250) NOT NULL,
`directorycompany_id` INT(11) NOT NULL,
`directorycontact_id` VARCHAR(250) NOT NULL,
`facebook_link` VARCHAR(250) DEFAULT NULL,
`twitter_link` VARCHAR(250) DEFAULT NULL,
`wikipedia_link` VARCHAR(250) DEFAULT NULL,
`web` VARCHAR(250) DEFAULT NULL,
`imageextension` VARCHAR(10) DEFAULT NULL,
`type` VARCHAR(20) NOT NULL DEFAULT 'other',
PRIMARY KEY (`id`)
) ENGINE=MYISAM AUTO_INCREMENT=1161 DEFAULT CHARSET=utf8;
The Foreign Key will be the id of directoryprogramme
The problem is the last line of your create statement:
ENGINE=INNODB DEFAULT CHARSET=utf8;
You mix MYISAM in ald table with INNODB in your new table.
That doesn't work.
Chnage the engine in your new table to MYISAM and it works.

cannot add second FK : got error can't create table'.jobstatus\#sql-32c_12f2f.frm' (errno:150)

CREATE TABLE `job` (
`jobId` int(11) NOT NULL auto_increment,
`jobcode` varchar(25) default NULL,
`jobname` varchar(255) default NULL,
`location` varchar(255) default NULL,
`budget` int(10) unsigned default NULL,
`year_type` varchar(100) default NULL,
`worklineId` int(11) default NULL,
PRIMARY KEY (`jobId`),
KEY `NewIndex` (`worklineId`),
FOREIGN KEY (`worklineId`) REFERENCES `workline` (`worklineId`)
) TYPE=InnoDB;
CREATE TABLE `subjob` (
`subjobId` int(11) NOT NULL auto_increment,
`subjobcode` varchar(25) default NULL,
`subjobname` varchar(255) default NULL,
`subjobbudget` int(11) unsigned default NULL,
`jobgoal_date` date default '0000-00-00',
`jobId` int(11) default NULL,
PRIMARY KEY (`subjobId`),
KEY `NewIndex` (`jobId`),
FOREIGN KEY (`jobId`) REFERENCES `job` (`jobId`)
) TYPE=InnoDB;
CREATE TABLE `contract` (
`contractId` int(11) NOT NULL auto_increment,
`contractcode` varchar(25) default NULL,
`price` int(11) unsigned default NULL,
`contractprice` int(11) unsigned default NULL,
`company` varchar(50) default NULL,
`signdate` date default '0000-00-00',
`begindate` date default '0000-00-00',
`enddateplan` date default '0000-00-00',
`note` text,
PRIMARY KEY (`contractId`)
) TYPE=InnoDB;
CREATE TABLE `subjob_contract` (
`subjobcontractId` int(11) NOT NULL auto_increment,
`status` varchar(11) default NULL,
`contractId` int(11) default NULL,
`subjobId` int(11) default NULL,
PRIMARY KEY (`subjobcontractId`),
KEY `NewIndex` (`contractId`),
KEY `NewIndex2` (`subjobId`),
FOREIGN KEY (`contractId`) REFERENCES `contract` (`contractId`)
) TYPE=InnoDB
I m using mysql front 3.2 to manage database,I can add first fk but when i add second fk i got an error following this :
sql execution error #1005. response from the database: can't create table'.jobstatus#sql-32c_12f2f.frm' (errno:150). i already define the new index for fk subjobId reference to subjob table what could be the possibility of this error? thank you
Check the datatype and size of the subjobId column on primary table and referenced table. both must be same than it will allow you to create foreign key.
Answer is: You can not refer that column/table which is not created yet. Try to execute tables having foreign keys after the referenced tables.
Obviously you should have consistency in datatypes of foreign key and referenced column as well
Correct Execution Demo. Also You should use Engine=InnoDB instead of Type=InnoDB