November 8, 2011 at 11:31 am
Can someone give me a nudge with the logic to use to identify only the FKs with trailing numbers? I think I need an expression that will identify a string with a number on the end of it...but I can't find such an expression.
I am trying to delete only *duplicate* FKs in my database. Thanks to Michael Sondergaards query I have a way to identify and label them with a trailing number.
EG.
FK_Schema.Table.Column_Schema.Table_Column
FK_Schema.Table.Column_Schema.Table_Column2
FK_Schema.Table.Column_Schema.Table_Column3
(I want to delete only FKs 2 and 3). Below is dynamic sql which deletes ALL FKs, so I need to refine it.
/* SUMMARY
(1)this dynamic SQL deletes all FKs in the database!
*/
---retrieves all FKs and puts in temporary table called @FK
USE MGONextGen
GO
DECLARE @FK varchar(max)
DECLARE getFKName CURSOR FOR
SELECT distinct
RC.Constraint_Name
FROM
information_schema.referential_constraints RC JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU ON
RC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU2 ON
RC.UNIQUE_CONSTRAINT_NAME = CCU2.CONSTRAINT_NAME
OPEN getFKName
FETCH NEXT
FROM getFKName INTO @FK
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
BEGIN TRANSACTION
declare @fk_name varchar (max)
declare @Table_Name varchar (max)
set @fk_name = @FK
SELECT distinct @Table_Name = RC.Constraint_Schema + '.' + CCU.Table_Name
FROM
information_schema.referential_constraints RC JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU ON
RC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU2 ON
RC.UNIQUE_CONSTRAINT_NAME = CCU2.CONSTRAINT_NAME
WHERE RC.Constraint_Name = @FK
print @Table_Name
print @fk_name
---- deletes FKs fetched by cursor
DECLARE @sql nvarchar(4000)
SET @sql = 'ALTER TABLE ' + @Table_Name + ' DROP CONSTRAINT ' + @FK
EXEC(@sql)
COMMIT TRAN
END TRY
BEGIN CATCH
print 'Catch'
IF ( XACT_STATE() !=0)
ROLLBACK TRAN;
SELECT @FK + ERROR_MESSAGE() AS [drop failed];
END CATCH
FETCH NEXT
FROM getFKName INTO @FK
END
CLOSE getFKName
DEALLOCATE getFKName
November 8, 2011 at 5:25 pm
I think this will work
where RC.Constraint_Name LIKE '%[0-9]%'
November 8, 2011 at 6:57 pm
That's a start. Are you sure you have no FKs with intermediate digits? Also, have you verified by definiton that the FKs are actually duplicates?
--Jeff Moden
Change is inevitable... Change for the better is not.
November 9, 2011 at 7:16 am
As far as having identified the duplicates, I think Michael Sondergaards sproc works really well for that and I have examined the results. Works good.
But, I agree with the reservations. I made no accommodation for FKs comprised of column names that may end with a number. I would like my expression to be more refined so that it recognizes a defacto duplicate, which is going to be two FK names that are exactly the same, and different by only a trailing number. If there are more than 9 duplicates than I need to accommodate a trailing two digit number. This sounds like overkill to some, but Murphey's law....
Any ideas?
November 9, 2011 at 10:29 am
Why not use ROW_NUMBER() instead of appending a number to the end of the name? Then you delete where row_number > 1
Jack Corbett
Consultant - Straight Path Solutions
Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
November 9, 2011 at 3:47 pm
hxkresl (11/9/2011)
As far as having identified the duplicates, I think Michael Sondergaards sproc works really well for that and I have examined the results. Works good.
You sure about that? I could be wrong but from where I sit, it would appear that the only thing Michael's code looks for is duplicate names. What about duplicate FK's that have different names?
--Jeff Moden
Change is inevitable... Change for the better is not.
November 9, 2011 at 4:48 pm
here's what i use, that finds FK duplicates regardless of any naming conventions...it uses row_number as suggested:
it also assumes only simple, single column FK, and not multi column FK's
SELECT
'ALTER TABLE ' + FKTABLE + ' DROP CONSTRAINT '+ CONSTRAINTNAME AS CMD,*
FROM (
SELECT
row_number() over (partition by FKTABLE,FKCOLUMN order by FKTABLE) as RW,*
FROM (
SELECT
OBJECT_NAME(constid) AS CONSTRAINTNAME,
OBJECT_NAME(rkeyid) AS REFTABLE,
COL_NAME(rkeyid,rkey) AS REFCOLUMN,
OBJECT_NAME(fkeyid) AS FKTABLE,
COL_NAME(fkeyid,fkey) AS FKCOLUMN,
' ALTER TABLE ' + OBJECT_NAME(fkeyid)
+ ' ADD CONSTRAINT ' + OBJECT_NAME(constid)
+ ' FOREIGN KEY (' + COL_NAME(fkeyid,fkey)
+ ') REFERENCES ' + OBJECT_NAME(rkeyid)
+'(' + COL_NAME(rkeyid,rkey) + ')' AS FKSQL
from sysforeignkeys
) x
) Y
WHERE RW > 1
ORDER BY FKTABLE,RW
Lowell
November 9, 2011 at 9:47 pm
Hi Jeff. Yep, his sproc identifies duplicate keys, not duplicate names. You can look at it as I've provided the link.
November 9, 2011 at 9:50 pm
Thanks Jack Corbett, I'll look at this row number solution. Appreciate it.
November 9, 2011 at 9:54 pm
Thank Lowell! Thanks for the demo on how to use rownumber with rank as more sophisticated alternative to my expression. Appreciate it.
Michael Sondergaards sproc is really smart. It identifies multicolumn FKs as well as single column. It is really sweet.
November 9, 2011 at 10:46 pm
hxkresl (11/9/2011)
Hi Jeff. Yep, his sproc identifies duplicate keys, not duplicate names. You can look at it as I've provided the link.
I don't see a link anywhere..
Jack Corbett
Consultant - Straight Path Solutions
Check out these links on how to get faster and more accurate answers:
Forum Etiquette: How to post data/code on a forum to get the best help
Need an Answer? Actually, No ... You Need a Question
November 10, 2011 at 6:00 am
hxkresl (11/9/2011)
Hi Jeff. Yep, his sproc identifies duplicate keys, not duplicate names. You can look at it as I've provided the link.
I agree with Jack Corbett. I might simply be missing it but I don't see a link anywhere.
--Jeff Moden
Change is inevitable... Change for the better is not.
November 10, 2011 at 6:12 am
Hi there. Sorry, here it is
http://www.sqlservercentral.com/scripts/constraints/71340/ .
November 10, 2011 at 7:49 am
hxkresl (11/10/2011)
Hi there. Sorry, here it ishttp://www.sqlservercentral.com/scripts/constraints/71340/ .
Ah... got it. Thanks. My previous comments were based on the code you posted.
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply