Reputation: 2871
I have inherited a database design that has a somewhat important flaw: the primary key of a core table (referenced by roughly half the other tables, many of which have constraints which check it) is a varchar(20).
This boggled my mind for a bit, but the rationale behind it is sensible. The number (and to date, they've always been numbers) is a combination of two fields of data (which are guaranteed to be unique when combined) but frequently starts with one or more 0s.
I'm sure there are better ways to solve this problem, but a complete change of the database schema is out of scope at the moment.
The problem is that we have a new client who has a combined ID which is 25 characters.
When we created the database for this client's site, I updated all the fields. This took me most of a day - I haven't done a lot with SQL at the table-creation/modification level, there are roughly 25 tables which reference this field (and a dozen or more stored procedures which take it's value in as a parameter) and each table has numerous constraints that have to be dropped so the table can be edited.
In total, updating the one database took me almost a full work day. It was long, boring work, yet a single typo could have broken the database schema. I had to write a script that dropped constraints from the tables in the right order, updated all the fields, and re-added all the constraints.
Is there an easier way to do this? I have to change the field length of a primary key that is also a foreign key on 20-25 tables, and I have to do it for roughly 8 different databases. The constraints have subtly different names on each database, so my script for the one won't work for the others.
Upvotes: 0
Views: 1206
Reputation: 1555
There are two ways.
is not recommended and very "intrusive".
All schemas are stored in table sys
, where you can find tables
, columns
and other tables. You have to prepare an UPDATE
query to change the needed values - this will affect the tables, schemas, columns and whatever you want directly.
It's not trivial though, as noone is allowed to UPDATE/DELETE sys tables. There are some workarounds, but I didn't try any of them on my own.
From information schema of your database collect the tables you want to change:
SELECT 'ALTER TABLE ' + TABLE_NAME + ' ALTER COLUMN ' + COLUMN_NAME + ' ' + DATA_TYPE + '(100)' AS [Edit],
TABLE_NAME,
COLUMN_NAME,
CASE
WHEN CHARINDEX('numeric',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(NUMERIC_PRECISION AS varchar) + ', ' + CAST(NUMERIC_SCALE as varchar) + ')'
WHEN CHARINDEX('varchar',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH as varchar) + ')'
ELSE DATA_TYPE
END AS TYP
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_NAME like '%'
AND TABLE_SCHEMA like '%'
AND CASE
WHEN CHARINDEX('numeric',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(NUMERIC_PRECISION AS varchar) + ', ' + CAST(NUMERIC_SCALE as varchar) + ')'
WHEN CHARINDEX('varchar',DATA_TYPE) <> 0 THEN DATA_TYPE + '(' + CAST(CHARACTER_MAXIMUM_LENGTH as varchar) + ')'
ELSE DATA_TYPE
END = 'varchar(50)'
Adjust it, run it, copy [Edit] column and paste it into SSMS and run again.
Upvotes: 1