添加检查以修改列的长度,删除并在一个块中添加默认值

时间:2017-10-11 14:11:37

标签: sql sql-server

我添加了对Varchar列的检查,我要修改其LENGTH及其default value

table = 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

1 个答案:

答案 0 :(得分: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