【问题标题】:add checking to modify the length of a column ,drop and add the default value in one block添加检查以修改列的长度,在一个块中删除并添加默认值
【发布时间】:2017-10-11 14:11:37
【问题描述】:

我添加了一个检查 Varchar 列,我想修改它的 LENGTH 和它的 default value

表=EX_EMPLOYEE列=TV_CODE长度=10

我的问题:我做了 3 个块来更改长度,然后删除默认值并添加一个新值。我可以一次性完成吗? 下面有没有替代方法,它的代码真的很长,我可以用更少的条件和 coes 更好地检查吗?

BEGIN
DECLARE @OLD_LENGTH numeric(4)
DECLARE @isnull numeric(4)
DECLARE @null_value varchar(10)

SELECT @OLD_LENGTH= c.length,
       @isnull = c.isnullable
FROM syscolumns c
WHERE c.id = OBJECT_ID('EX_EMPLOYEE') AND c.name = 'TV_CODE'
if @isnull =1 
select @null_value='NULL'
else
select @null_value='NOT NULL'
IF @@ROWCOUNT =0
begin
 EXECUTE ('ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11) '+@null_value)
end
 if  @OLD_LENGTH <11
 EXECUTE ('ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11)'+ @null_value)
 END
GO
begin
DECLARE @df_value varchar(500)
select @df_value = d.name from sys.all_columns c join sys.tables t on t.object_id = c.object_id join sys.schemas s on s.schema_id = t.schema_id
join sys.default_constraints d on c.default_object_id = d.object_id
where t.name = 'EX_EMPLOYEE' and c.name = 'TV_CODE'
  if @df_value is not null
    begin
    EXECUTE ('ALTER TABLE EX_EMPLOYEE DROP CONSTRAINT '+ @df_value)
    end
end
go

IF EXISTS (SELECT 1 FROM sys.all_columns c WHERE c.object_id = OBJECT_ID('EX_EMPLOYEE') 
AND c.name = 'TV_CODE')
and NOT EXISTS(select * from sys.all_columns c join sys.tables t on t.object_id = c.object_id join sys.schemas s on s.schema_id = t.schema_id
join sys.default_constraints d on c.default_object_id = d.object_id
where t.name = 'EX_EMPLOYEE' and c.name = 'TV_CODE')
BEGIN
EXECUTE ('ALTER TABLE EX_EMPLOYEE ADD DEFAULT ''A'' for TV_CODE')
END
GO

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您的代码没有任何问题。它可以作为一个“块”来完成,并且有一些方法可以让它更有效率,但是你正在做的事情需要多个步骤,所以它不会很短。以下是我的做法,基于以下假设:

    • 一切都在 DBO 架构中
    • 如果列长度小于 11,则执行所有操作,否则不执行任何操作

    (我,我想确定列总是 NULL 或 NOT NULL,并且不会因表实例而异。使用此脚本执行此规则是明智的.)

    DECLARE
      @CurrentLength  smallint
     ,@IsNull         bit
     ,@Command        nvarchar(200)
     ,@Debug          bit = 1
    
    
    --  Get current settings.  Note that variables are set to same dataype as is used in the tables
    --  Also, always use the system tables in the "sys" schema
    SELECT
       @CurrentLength = max_length
      ,@IsNull        = is_nullable
     from sys.columns
     where object_id = object_id('EX_EMPLOYEE')
      and name = 'TV_CODE'
    
    
    IF @CurrentLength < 11
     BEGIN
        --  Table AND column exist, column is under 11 characters, so proceed with everything
    
    
        --  Here, reset column to varchar(11)
        SET @Command = 'ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11) '
         + case @IsNull
             when 1 then 'NULL'
             else 'NOT NULL'
           end
    
        --  Whenever possible (which I think is always), use sp_executeSQL instead of EXECUTE()
        IF @Debug = 1
            --  Makes it easier to debug dynamic code
            PRINT @Command
    
        EXECUTE sp_executesql @Command
    
    
        --  Going to cheat here and adapt code from a prior answer https://stackoverflow.com/questions/1430456/how-to-drop-sql-default-constraint-without-knowing-its-name/1433384#1433384
        SET @Command = null
    
        SELECT @Command = 'ALTER TABLE EX_EMPLOYEE drop constraint ' + d.name
         from sys.tables t
          inner join sys.default_constraints d
           on d.parent_object_id = t.object_id
          inner join sys.columns c
           on c.object_id = t.object_id
            and c.column_id = d.parent_column_id
         where t.name = 'EX_EMPLOYEE'
          and c.name = 'TV_CODE'
    
    
        IF @Debug = 1
            --  Continues to make it easier to debug dynamic code
            PRINT @Command
    
        --  If there is no constraint, @Command will be null
        IF @Command is not null
            EXECUTE sp_executesql @Command
    
    
        --  Now create the default.  Give it a name, so we don't have to play "go fish" the next time around.
        --  Dynamic SQL is not required here.
        ALTER TABLE EX_EMPLOYEE
         add constraint DF_EX_EMPLOYEE__TV_CODE
          default 'A' for TV_CODE
    
     END
    GO
    

    【讨论】:

    • 我有一些问题,您是否添加了检查的默认值?如果列不存在默认值,会报错吧?
    • 添加默认约束对现有数据没有影响。这需要update 声明。
    • 第二部分构建一个“删除约束”语句,如果有一个约束要删除。如果没有约束要放弃,它什么也不做。这样一来,当我们进入“创建约束”部分时,该列将不会有任何约束来干扰创建。
    • 在这个语句SELECT @Command = 'ALTER TABLE EX_EMPLOYEE drop constraint ' + d.name...如果我执行它,如果d.name为null它不会抛出错误?
    • 它是 SELECT 语句的一部分。如果选择返回一行,则引用的列 (d.name) 不能为空,因为连接和基础表结构的逻辑。如果没有返回任何行,@Command 的值将不会被修改,这就是为什么我们在它之前有SET @Command = null。永远不要忘记,(任何东西)+ NULL = NULL。最后,在 EXECUTE 语句之前,我们检查 @Command 是否为 NULL,如果是,我们什么也不做……我敢肯定,执行 NULL 语句什么都不会,即使通过了也不会引发错误。
    猜你喜欢
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多