SQL for Smarties | SQL Programming Style | Trees and Hierarchies in SQL | SQL Puzzles and Answers | Data and Databases


Friday, May 11, 2007

Correct Way to Insert into Multiple Tables

SQL Apprentice Question
I am just wondering if what I am doing would be considered the correct
way to insert data into multiple tables when a forigen key is in place
between the tables primary keys.


Here is a simple DB structure
Table 1
ID int (auto incriment) Primary Key
FirstName varchar(100)
LastName varchar(200)


Table 2
ID (Primary Key)
Age int
BirthPlace varchar(100)


I have created the following sotred proceedure, it works from the test I
have done, but I am wondering if it is the *correct* way to do it.


PROCEDURE [dbo].[InsertPerson]
@ID int output,
@FirstName varchar(100),
@LastName varchar(200),
@Age int,
@BirthPlace varchar(100)
AS
Insert into dbo.UserInfo(FirstName, LastName)
Values(@FirstName, @LastName)
SET @ID = SCOPE_IDENTITY()


Insert into dbo.UserDetails(ID, Age, BirthPlace)
Values (@ID, @Age, @BirthPlace)



Celko Answers

>> I am just wondering if what I am doing would be considered the correct way to insert data into multiple tables when a forigen key is in place between the tables primary keys. <<


Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, data types, etc. in
your schema are. Sample data is also a good idea, along with clear
specifications. It is very hard to debug code when you do not let us
see it.

And what you have done is wrong on several points.


1) an auto-increment cannot ever be used as a key in an RDBMS. A key
is a subset of attributes in the data model. An auto-increment is
inside the hardware and has nothing to do with the data model,


2) Do you really have names that long? Well, you will if you allow
it,


3) Why did you split information of what-ever-the-heck you are
modeling across two tables?


4) "age" of what? Ands we never store age; we store a birthdate so we
can always correctly compute the age. Is this what you wanted?


CREATE TABLE Customers
(cust_id CHAR(9) NOT NULL PRIMARY KEY
CHECK (<< validation constraint>>),
last_name VARCHAR(20) NOT NULL,
first_name VARCHAR(20) NOT NULL,
birth_date DATETIME NOT NULL,
birth_location VARCHAR(20) NOT NULL);


The problem goes away with a valid design. I think what you might
have wanted to know is that INSERT INTO statements work on one and
only one base table. Put both inserts into a single transaction and
add a PRIMARY KEY and FOREIGN KEY constraints.

1 comment:

Hilarion said...

I agree, that the original question shows many flaws in the designers data model and that the first action that should be taken is to correct the model, probably by not splitting the data in two tables and using some kind birth date (depending on required and/or available precision it could be birth year) in place of age. I do not agree however that using auto-increment fields is always an error. Yes, auto-increment is bad in data model, but not in that data model implementation. In many cases using natural keys would make the DB grow in size to fast and make querying awkward and slow. There are also cases when there's no usable natural key at all, when only human decision makes two entities distinct or not. I do think, that one should have natural key in data models whenever it's possible, but it's not always possible and it's not always best to use it for referential integrity constraints.