addは

2017-10-11 9 views
0

私は=私はそのLENGTHを変更するVARCHAR列にチェックし、そのdefault valueaddは

テーブル= EX_EMPLOYEE列を追加しましたTV_CODE長さ=

私の問題:長さを変更してデフォルト値を削除し、新しい値を追加するために3ブロックを作成しました。私は1つのブロックでそれを行うことはできますか? その下の代替方法として、本当に長いコードを使用すれば、条件やコアを少なくしてより良いチェックを行うことができますか?

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) '[email protected]_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

コードに問題はありません。 1つの「ブロック」として実行することもできますが、それをより効率的にする方法もありますが、実行する処理には複数のステップが必要なため、短くはありません。ここで私は以下の仮定に基づいて、それを行わないと思います方法は次のとおりです。何もそれ以外の場合は行うには、列の長さが11未満の場合、

  • すべてはDBOスキーマ
  • である全力を尽くす

(私、私は列が常に 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 
+0

私はいくつかの質問があります、あなたはチェックを追加したデフォルト値ですか?列にデフォルト値が存在しない場合は、エラーが発生しますか? – Moudiz

+0

デフォルトの制約を追加しても、既存のデータには影響しません。これには 'update'ステートメントが必要です。 –

+0

2番目のセクションでは、ドロップ制約がある場合はドロップ制約文を作成します。ドロップする制約がない場合、何もしません。このようにして、「制約を作成する」セクションに入ると、その列が作成を妨げる制約はありません。 –