I've been helping a client get a custom database application working for a while. The previous vendor never quite completed it, then got testy when the client brought me in. When the vendor told them "either he goes or we go," my client said "see ya." Fortunately the client got me the entire code base, and as their de facto network administrator I already had dbo access to the database.
dbo
There are two unbelievably bad things about the vendor's data design that I want to share. First, they created a table called "passwords" that has user passwords in plain text. I would expect that even non-programmers of reasonable intelligence can intuitively grasp why this horrifies me, but apparently the vendor's crack team of coders had no problem with this design. It horrified my client when I casually connected to the database using a Microsoft Access and executed the query "select * from passwords".
select * from passwords
The second problem is more subtle, in the way that spilling hot coffee on yourself would be a more subtle effect of a rear-end auto collision than the crunching metal and plastic part of it. Throughout their database, instead of using int primary keys as most people do, they concocted this method of creating row IDs based on some piece of data in the row followed by a four-digit number. For example, the accounts table might have an entry for "Inner Drive Technology" whose row ID would be something like "Inne1024". And they leave it up to the ASP.NET code to create the IDs. And none of the ID columns has a UNIQUE constraint on it.
int
accounts
UNIQUE
Can you think why the application sometimes has trouble retrieving data?
Because I'm in triage mode right now, I don't have time to design a proper database, but I at least created these objects to minimize the likelihood that inserts will fail:
CREATE TABLE next_id ( last_id int NOT NULL ) GO INSERT next_id (last_id) VALUES (2000) GO GRANT SELECT, UPDATE ON next_id TO PUBLIC GO CREATE PROC GetNextId @TextValue varchar(512), @Result ACCOUNT_ID OUTPUT AS BEGIN DECLARE @FirstFour char(4) SET @FirstFour = SUBSTRING(RTRIM(@TextValue) + '000', 1, 4) BEGIN TRANSACTION DECLARE @LastId int SET @LastId = (SELECT MAX(last_id) FROM next_id) DECLARE @NextId int SET @NextId = @LastId + 1 SET @Result = (@FirstFour + '' + CAST(@NextId as varchar) ) UPDATE next_id SET last_id = @NextId WHERE last_id = @LastId COMMIT END GO GRANT EXEC ON GetNextId TO PUBLIC GO
It's what my wife would call a "Hoosier" solution, but at least it guarantees that row IDs are, in fact, unique.