9

私はデータベースを持っており、多くのビット型の列があります。他の列を追加した後、すべての古い列にデフォルトの「false」値を設定する必要があります。

4

2 に答える 2

22

古い各列を0に更新するには、次のクエリを使用できます(列ごとに)。

UPDATE MyTable
SET OldCol1 = 0
WHERE OldCol1 IS NULL

次に、将来の値にもデフォルトを0にしたい場合は、次を使用します。

ALTER TABLE MyTable
ALTER COLUMN OldCol1 bit NOT NULL

ALTER TABLE MyTable
ADD CONSTRAINT OldCol1ShouldBeFalse DEFAULT 0 FOR OldCol1

これを古い列ごとに実行する必要があるので、多すぎないことを願っています。

于 2012-09-06T13:46:03.377 に答える
3

これを1つずつ実行したくない場合は、このネストされた動的SQLが仕事を達成します。列にデフォルトの制約がまだないことを検証するためのチェックは最初に行わないことに注意してください (列が null 許容であっても可能です)。デフォルトの場合のそのような制約 1)。

DECLARE @sql NVARCHAR(MAX);
SET @sql = N'DECLARE @sql NVARCHAR(MAX); SET @sql = N'''';';

SELECT @sql = @sql + N'
  SELECT @sql = @sql + N''UPDATE ' + QUOTENAME(name) 
  + '.'' + QUOTENAME(s.name) + ''.'' + QUOTENAME(t.name) + '' 
  SET '' + QUOTENAME(c.name) + '' = 0 
  WHERE '' + QUOTENAME(c.name) + '' IS NULL;

  ALTER TABLE ' + QUOTENAME(name) + '.'' + QUOTENAME(s.name) 
    + ''.'' + QUOTENAME(t.name) 
    + '' ADD CONSTRAINT '' + c.name + ''_FalseByDefault 
    DEFAULT (0) FOR '' + QUOTENAME(c.name) + '';

  ALTER TABLE ' + QUOTENAME(name) + '.'' + QUOTENAME(s.name) 
    + ''.'' + QUOTENAME(t.name) 
    + '' ALTER COLUMN '' + QUOTENAME(c.name) + '' BIT NOT NULL;
  ''

FROM ' + QUOTENAME(name) + '.sys.columns AS c
INNER JOIN ' + QUOTENAME(name) + '.sys.tables AS t
ON c.[object_id] = t.[object_id]
INNER JOIN ' + QUOTENAME(name) + '.sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE c.system_type_id = 104 AND c.is_nullable = 1
AND t.is_ms_shipped = 0;'
FROM sys.databases WHERE database_id > 4;

SET @sql = @sql + 'PRINT @sql;
  --EXEC sp_executesql @sql;';

EXEC sp_executesql @sql;

これは非常に見苦しくPRINT、Management Studio の出力制限により、コマンドは必ずしも完全ではありません。ただし、最初のいくつかのコマンドが正しく表示されることを確認したら、それをコメント アウトし、最後の 2 行目のコメントを解除して、スクリプトを再度実行して変更を加えることができます。一部が失敗する可能性があるため、GOはそこにあります。潜在的なエラーを実際のデータベース/テーブル/列とより簡単に関連付けるためにステータス メッセージを出力できるように、データベース/テーブル/列の組み合わせごとに印刷出力を追加することができます。

于 2012-09-06T14:26:06.223 に答える