Internet Strategy Guide

Together we can defeat the internet

Monday, July 13, 2009

mysql alter table add foreign key

I recently ran into a situation where I needed to add a foreign key to a table. This seems easy at first but was actually a 3 step process compared to the couple of lines it takes in a create table sytax.

Short version: when creating your FK column, it helps to have the column definition of the FK match the column definition. In retrospec, this seems like a no-brainer but was the heart of my problem.

So, you want create a FK to an existing table. Lets start by creating our table.

CREATE TABLE IF NOT EXISTS Role(
Id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR(255) NOT NULL UNIQUE,
Description TEXT DEFAULT NULL,
PRIMARY KEY(Id)
);

Pretend we pooped data into it and now it's a big pain in the ass to do a drop/create with how we want things.

First we add our column that will be the Foreign Key.

ALTER TABLE Role ADD COLUMN Parent int(11) UNSIGNED DEFAULT NULL;

Next we add an index. Why? because mysql says so and FKs rely on indexes

ALTER TABLE Role ADD INDEX Parent (Parent);

Now we add our constraint.

ALTER TABLE `Role` ADD CONSTRAINT `Parent` FOREIGN KEY(`Parent`) REFERENCES `Role`(`Id`) ON DELETE SET NULL ON UPDATE SET NULL;

For fun, do

ALTER TABLE Role ADD COLUMN Parent int(11) DEFAULT NULL;

for the first step. Everything will look awesome until you get to the the last step. You'll get a wonderful "Errno 150" error and spend a bunch of time googling various key words trying to figure out what went wrong. Well, at least I did.

posted by chance at 9:20 am  

Friday, November 14, 2008

INSERT INTO `table` (`column`,`col2`) VALUES isn’t completely worthless

In most cases, when doing an insert statement I use SET to increase readability. It is also nice because I can make dynamic statements with insert/update. It is because of these two reasons I never saw any value (for lack of a better term that isn't punny) to using VALUES. That is until I ran into a situation where I wanted to have a database level solution as opposed to making an application layer solution. The situation is as follows:
- create an entry in the parent table
- create entries in the child table that depends on the last insert id of the parent table.

Now that I think about it, there may have been a way to do it procedurally in SQL but the first solution I was stuck on how to make my next INSERT statement fulfill my criteria and be readable. This is where VALUES comes in. By using VALUES instead of SET, you can do a multi-row insert statement.

example:

INSERT INTO Resource SET ModuleID=LAST_INSERT_ID(), Name='contact', Description='Contact resource in the default module';
/* multi-row insert */
INSERT INTO Privilege (ResourceID,Name,Description) VALUES
	(LAST_INSERT_ID(),'*','All privileges for this resource'),
	(LAST_INSERT_ID(),'browse','Browse only privilege for this resource'),
	(LAST_INSERT_ID(),'read','Read only privilege for this resource'),
	(LAST_INSERT_ID(),'edit','Edit only privilege for this resource'),
	(LAST_INSERT_ID(),'add','Add only privilege for this resource'),
	(LAST_INSERT_ID(),'delete','Delete only privilege for this resource');

So now, VALUES isn't completely useless after all.

posted by chance at 1:03 pm  

Tuesday, March 18, 2008

Pwning your MySQL

How to find out if a specific column exists:

SHOW COLUMNS FROM TableName WHERE Field LIKE ('ColName')

posted by chance at 10:13 am  

Powered by WordPress