1

私たちのソフトウェアを使用している一部の人々は、すべてのデータベースでレンダリングするソフトウェアのレガシー部分に対応する通常の手順に従わずに、データベース サーバーの移動を行っていnulls = 0ます。したがって、彼らは私たちのプロトコルの使用を無視したため、多くの不要な null データと、代わりに truefieldname = 0が原因で失敗した多くのクエリが残されています。fieldname is null

では、ストアド プロシージャを構築して、すべての null (実際には null はないはずです) を SQL Server データベースの既定値に戻すにはどうすればよいでしょうか。

私はストアド プロシージャを実行した経験がほとんどなく、ストアド プロシージャで Oracle DB 以外の経験がまったくないので、コード サンプルでこれに答えることができれば、コードが何をしているのか説明してください。その場合は、それを行うためのユーティリティを作成するだけです(ただし、そのユーティリティの実行に9年かかることはすでにわかっています)

4

3 に答える 3

3

あなたのタイトルはフィールドをnullに設定すると言っていますが、あなたの質問にはnullがあってはならないと言われています。それにもかかわらず....DEFAULTキーワードを使用して、フィールドをデフォルト値に設定できます。

Update MyTable set MyField = DEFAULT Where <something>
于 2012-10-08T16:29:01.643 に答える
3

これにより、テーブル内のすべての null 許容列が一覧表示されます。

select tab.name, col.name 
from sys.columns col join sys.tables tab on col.object_id = tab.object_id
where tab.type = 'U' and col.is_nullable = 1

カーソルを使用してそれぞれをループし、動的 ​​SQL を実行して列定義を更新する可能性があります。しかし、各列に異なるデータ型がある場合、それは非常に厄介なことになる可能性があります.それらはすべて同じですか?

または、すべての SP クエリを更新して使用することもできます。

ISNULL(fieldname, 0) = 0

その側から NULL 問題を排除する - これは NULL またはゼロに一致します。

編集:

INT、TINYINT、BIGINT、および BIT のすべての列を更新する場合は、このスクリプト実行できます。ただし、自己責任で使用してください。DB をバックアップし、コピーとして復元し、そこでテストします。次に、WHERE 句のテーブル フィルターのコメントを外して、最初に 1 つのテーブルでテストします。EXEC にはコメントが付けられていますが、テストしてスクリーニングしてからコメントを外してください。

このスクリプトは次のことを行います。

  1. すべての NULL INT、TINYINT、BIGINT、および BIT をゼロに更新 (false)
  2. すべての INT、TINYINT、BIGINT、および BIT 列を NOT NULL に変更する
  3. デフォルトの制約をすべての INT、TINYINT、BIGINT、および BIT 列にゼロ (false) に追加します。

列にデフォルトの制約が既にある場合、3 は失敗することに注意してください。デフォルト値が必要ない場合 (つまり、INSERT ごとに明示的に値を挿入する場合) は削除してください。

DECLARE @table VARCHAR(MAX), @col VARCHAR(MAX), @type VARCHAR(MAX)
DECLARE @q_update VARCHAR(MAX), @q_alter VARCHAR(MAX), @q_default VARCHAR(MAX)

DECLARE c CURSOR FOR

    select tab.name, col.name, typ.name
    from sys.columns col
          join sys.types typ on col.system_type_id = typ.system_type_id
          join sys.tables tab on col.object_id = tab.object_id

    where tab.type = 'U' and col.is_nullable = 1 and typ.name IN ('int', 'tinyint', 'bigint', 'bit')
    --tab.name = 'sometable'

OPEN c
FETCH NEXT FROM c INTO @table, @col, @type
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'UPDATING ' + @table + '.' + @col + ' (' + @type + ')';

    SET @q_update = 'UPDATE [' + @table + '] SET [' + @col + '] = 0 WHERE [' + @col + '] IS NULL';
    PRINT @q_update;
    --EXEC(@q_update);

    PRINT '';

    SET @q_alter = 'ALTER TABLE [' + @table + '] ALTER COLUMN [' + @col + '] ' + @type + ' NOT NULL';
    PRINT @q_alter;
    --EXEC(@q_alter);

    PRINT '';

    SET @q_default = 'ALTER TABLE [' + @table + '] ADD CONSTRAINT ' + @table + '_' + @col + '_DF DEFAULT 0 FOR [' + @col + ']'
    PRINT @q_default;
    --EXEC(@q_default);

    PRINT '----';

    FETCH NEXT FROM c INTO @table, @col, @type
END
CLOSE c
DEALLOCATE c

注: わかりやすくするためにカーソルを使用しました。本当に使いたくない場合は、@JamesCurtisリンクを自由に見てください。

于 2012-10-08T16:35:46.117 に答える
1

これがあなたが必要とすることを達成するコードサンプルです。

大規模な免責事項。このコードは、デフォルトを持つすべてのnull許容列をデフォルトにリセットします。ほぼ確実に、その範囲を制限する必要があります。

-- Routine which finds all NULLABLE columns with default values
-- and sets them back to their defaults.

-- DISCLAIMER.  If in any doubt, comment the EXEC out and copy and paste
-- the contents of @sql into a query window, and inspect before running.

-- Soon to hold executable SQL
DECLARE @sql VARCHAR(Max)

-- Use the INFORMATION_SCHEMA to find all qualifying columns, building
-- up a string consisting of a series of simple update statements
--
-- Warning:  My definition of qualifying may differ from yours.
-- Check your WHERE clause. 
--
-- Doity concatenatin' ahoy, Captain!
SELECT
    @sql = 
    CASE WHEN
        @sql IS NULL
    THEN
        'UPDATE ' + TABLE_NAME + ' SET ' + COLUMN_NAME + ' = DEFAULT;'  
    ELSE 
        @sql + 'UPDATE ' + TABLE_NAME + ' SET ' + COLUMN_NAME + ' = DEFAULT;'   
    END
FROM
    INFORMATION_SCHEMA.COLUMNS
WHERE 
    COLUMN_DEFAULT IS NOT NULL
AND IS_NULLABLE = 'YES'
--  Add extra conditions for granularity!!!!

-- Execute sql
EXEC (@sql);
于 2012-10-08T17:01:26.607 に答える