1. ホーム
  2. sql-server

SQL Server の全テーブルの全カラムの照合順序を変更する

2023-10-27 04:07:52

質問

あるデータベースをインポートして、別のデータベースと比較するために、いくつかのデータをインポートしました。

ターゲットデータベースは照合順序が Latin1_General_CI_AS で、ソースデータベースは SQL_Latin1_General_CP1_CI_AS .

私は、ソースデータベースの照合順序を全般的に Latin1_General_CI_AS に変更しました。しかし、中のテーブルとカラムは、古い照合順序のままです。

を使用してカラムを変更できることは知っています。

ALTER TABLE [table] 
ALTER COLUMN [column] VARCHAR(100) COLLATE Latin1_General_CI_AS

しかし、私はすべてのテーブルと内部のすべてのカラムに対してこれを行う必要があります。

私はすべてのテーブルと内部のすべての列の型を読み取るストアドプロシージャを記述するために開始することを知っている前に varchar とテーブルと列のカーソルループでそれらを変更するストアドプロシージャを書き始める前に...

誰かもっと簡単な方法を知っていますか、それともプロシージャですべてのテーブルを実行するスクリプトでこれを行う唯一の方法ですか?

どのように解決するのですか?

私は適切な方法を見つけられなかったので、それを行うためのスクリプトを書きましたので、必要な人のためにここでそれを共有します。このスクリプトは、すべてのユーザー テーブルを実行し、カラムを収集します。もしカラムの型がchar型であれば、指定された照合順序に変換しようとします。

これが動作するためには、列はインデックスと制約がないことが必要です。

もし誰かがまだこれに対するより良い解決策を持っているなら、それを投稿してください!

DECLARE @collate nvarchar(100);
DECLARE @table nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @row_id int;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);

SET @collate = 'Latin1_General_CI_AS';

DECLARE local_table_cursor CURSOR FOR

SELECT [name]
FROM sysobjects
WHERE OBJECTPROPERTY(id, N'IsUserTable') = 1

OPEN local_table_cursor
FETCH NEXT FROM local_table_cursor
INTO @table

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE local_change_cursor CURSOR FOR

    SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS row_id
        , c.name column_name
        , t.Name data_type
        , c.max_length
        , c.column_id
    FROM sys.columns c
    JOIN sys.types t ON c.system_type_id = t.system_type_id
    LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
    LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
    WHERE c.object_id = OBJECT_ID(@table)
    ORDER BY c.column_id

    OPEN local_change_cursor
    FETCH NEXT FROM local_change_cursor
    INTO @row_id, @column_name, @data_type, @max_length, @column_id

    WHILE @@FETCH_STATUS = 0
    BEGIN

        IF (@max_length = -1) OR (@max_length > 4000) SET @max_length = 4000;

        IF (@data_type LIKE '%char%')
        BEGIN TRY
            SET @sql = 'ALTER TABLE ' + @table + ' ALTER COLUMN ' + @column_name + ' ' + @data_type + '(' + CAST(@max_length AS nvarchar(100)) + ') COLLATE ' + @collate
            PRINT @sql
            EXEC sp_executesql @sql
        END TRY
        BEGIN CATCH
          PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
          PRINT @sql
        END CATCH

        FETCH NEXT FROM local_change_cursor
        INTO @row_id, @column_name, @data_type, @max_length, @column_id

    END

    CLOSE local_change_cursor
    DEALLOCATE local_change_cursor

    FETCH NEXT FROM local_table_cursor
    INTO @table

END

CLOSE local_table_cursor
DEALLOCATE local_table_cursor

GO