Как удалить ограничение по умолчанию SQL, не зная его имени?
в Microsoft SQL Server я знаю запрос, чтобы проверить, существует ли ограничение по умолчанию для столбца и отбросить ограничение по умолчанию:
IF EXISTS(SELECT * FROM sysconstraints
WHERE id=OBJECT_ID('SomeTable')
AND COL_NAME(id,colid)='ColName'
AND OBJECTPROPERTY(constid, 'IsDefaultCnst')=1)
ALTER TABLE SomeTable DROP CONSTRAINT DF_SomeTable_ColName
но из-за опечатки в предыдущих версиях базы данных, имя ограничения может быть DF_SomeTable_ColName или DF_SmoeTable_ColName.
как я могу удалить ограничение по умолчанию без каких-либо ошибок SQL? Имена ограничений по умолчанию не отображаются в таблице INFORMATION_SCHEMA, что делает вещи немного сложнее.
так, что-то как удалить ограничение по умолчанию в этой таблице столбец " или " удалить DF_SmoeTable_ColName', но не дают никаких ошибок, если он не может найти его.
13 ответов:
расширяя код Mitch Wheat, следующий скрипт создаст команду для удаления ограничения и динамического его выполнения.
declare @schema_name nvarchar(256) declare @table_name nvarchar(256) declare @col_name nvarchar(256) declare @Command nvarchar(1000) set @schema_name = N'MySchema' set @table_name = N'Department' set @col_name = N'ModifiedDate' select @Command = 'ALTER TABLE ' + @schema_name + '.' + @table_name + ' drop constraint ' + d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and t.schema_id = schema_id(@schema_name) and c.name = @col_name --print @Command execute (@Command)
сообщение в блоге Роба Фарли может помочь:
что-то типа:
declare @table_name nvarchar(256) declare @col_name nvarchar(256) set @table_name = N'Department' set @col_name = N'ModifiedDate' select t.name, c.name, d.name, d.definition from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @col_name
Я обнаружил, что это работает и не использует соединения:
DECLARE @ObjectName NVARCHAR(100) SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName'; EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + @ObjectName)просто убедитесь, что columnName не имеет скобок вокруг него, потому что запрос ищет точное соответствие и ничего не вернет, если это [columnName].
чтобы удалить ограничение для нескольких столбцов:
declare @table_name nvarchar(256) declare @Command nvarchar(max) = '' set @table_name = N'ATableName' select @Command = @Command + 'ALTER TABLE ' + @table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13) from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name in ('column1','column2','column3') --print @Command execute (@Command)
расширенное решение (учитывает схему таблицы):
-- Drop default contstraint for SchemaName.TableName.ColumnName DECLARE @schema_name NVARCHAR(256) DECLARE @table_name NVARCHAR(256) DECLARE @col_name NVARCHAR(256) DECLARE @Command NVARCHAR(1000) set @schema_name = N'SchemaName' set @table_name = N'TableName' set @col_name = N'ColumnName' SELECT @Command = 'ALTER TABLE [' + @schema_name + '].[' + @table_name + '] DROP CONSTRAINT ' + d.name FROM sys.tables t JOIN sys.default_constraints d ON d.parent_object_id = t.object_id JOIN sys.schemas s ON s.schema_id = t.schema_id JOIN sys.columns c ON c.object_id = t.object_id AND c.column_id = d.parent_column_id WHERE t.name = @table_name AND s.name = @schema_name AND c.name = @col_name EXECUTE (@Command)
отбросьте все ограничения по умолчанию в базе данных - безопасный для порога nvarchar(max).
/* WARNING: THE SAMPLE BELOW; DROPS ALL THE DEFAULT CONSTRAINTS IN A DATABASE */ /* MAY 03, 2013 - BY WISEROOT */ declare @table_name nvarchar(128) declare @column_name nvarchar(128) declare @df_name nvarchar(128) declare @cmd nvarchar(128) declare table_names cursor for SELECT t.name TableName, c.name ColumnName FROM sys.columns c INNER JOIN sys.tables t ON c.object_id = t.object_id INNER JOIN sys.schemas s ON t.schema_id = s.schema_id ORDER BY T.name, c.name open table_names fetch next from table_names into @table_name , @column_name while @@fetch_status = 0 BEGIN if exists (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name) BEGIN SET @df_name = (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name) select @cmd = 'ALTER TABLE [' + @table_name + '] DROP CONSTRAINT [' + @df_name + ']' print @cmd EXEC sp_executeSQL @cmd; END fetch next from table_names into @table_name , @column_name END close table_names deallocate table_names
следующее решение отбросит определенное ограничение по умолчанию столбца из таблицы
Declare @Const NVARCHAR(256) SET @Const = ( SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name FROM Sys.default_constraints A JOIN sysconstraints B on A.parent_object_id = B.id WHERE id = OBJECT_ID('YOUR TABLE NAME') AND COL_NAME(id, colid)='COLUMN NAME' AND OBJECTPROPERTY(constid,'IsDefaultCnst')=1 ) EXEC (@Const)
выполните эту команду для просмотра всех ограничений:
exec sp_helpconstraint 'mytable' --and look under constraint_name.это будет выглядеть так:
DF__Mytable__Column__[ABC123]. Тогда вы можете просто отбросить ограничение.
У меня были некоторые столбцы, которые имели несколько ограничений по умолчанию, поэтому я создаю следующую хранимую процедуру:
CREATE PROCEDURE [dbo].[RemoveDefaultConstraints] @table_name nvarchar(256), @column_name nvarchar(256) AS BEGIN DECLARE @ObjectName NVARCHAR(100) START: --Start of loop SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS WHERE [object_id] = OBJECT_ID(@table_name) AND [name] = @column_name; -- Don't drop the constraint unless it exists IF @ObjectName IS NOT NULL BEGIN EXEC ('ALTER TABLE '+@table_name+' DROP CONSTRAINT ' + @ObjectName) GOTO START; --Used to loop in case of multiple default constraints END END GO -- How to run the stored proc. This removes the default constraint(s) for the enabled column on the User table. EXEC [dbo].[RemoveDefaultConstraints] N'[dbo].[User]', N'enabled' GO -- If you hate the proc, just get rid of it DROP PROCEDURE [dbo].[RemoveDefaultConstraints] GO
полезно для некоторых столбцов, которые несколько
default constraints or check constraintsсоздана:изменено https://stackoverflow.com/a/16359095/206730 скрипт
Примечание: этот скрипт для sys.check_constraints
declare @table_name nvarchar(128) declare @column_name nvarchar(128) declare @constraint_name nvarchar(128) declare @constraint_definition nvarchar(512) declare @df_name nvarchar(128) declare @cmd nvarchar(128) PRINT 'DROP CONSTRAINT [Roles2016.UsersCRM].Estado' declare constraints cursor for select t.name TableName, c.name ColumnName, d.name ConstraintName, d.definition ConstraintDefinition from sys.tables t join sys.check_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = N'Roles2016.UsersCRM' and c.name = N'Estado' open constraints fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition while @@fetch_status = 0 BEGIN print 'CONSTRAINT: ' + @constraint_name select @cmd = 'ALTER TABLE [' + @table_name + '] DROP CONSTRAINT [' + @constraint_name + ']' print @cmd EXEC sp_executeSQL @cmd; fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition END close constraints deallocate constraints
Я надеюсь, что это может быть полезно для тех, у кого есть подобная проблема . В
ObjectExplorerОкно, выберите вашу базу данных=> таблицы=> таблицы=> ограничения. Если клиент определен во время создания столбца, вы можете увидеть имя ограничения по умолчанию, включая имя столбца. затем используйте:ALTER TABLE yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295;(имя ограничения-это просто пример)
declare @ery nvarchar(max) declare @tab nvarchar(max) = 'myTable' declare @qu nvarchar(max) = 'alter table '+@tab+' drop constraint ' select @ery = (select bj.name from sys.tables as tb inner join sys.objects as bj on tb.object_id = bj.parent_object_id where tb.name = @tab and bj.type = 'PK') exec(@qu+@ery) **Take a look**
всегда создавайте сценарий и просматривайте его перед запуском. Ниже скрипт
select 'Alter table dbo.' + t.name + ' drop constraint '+ d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where c.name in ('VersionEffectiveDate','VersionEndDate','VersionReasonDesc') order by t.name
Comments