SQL Server - скрипт для обновления столбцов базы данных с varchar на nvarchar, если nvarchar еще не установлен

StackOverflow https://stackoverflow.com/questions/179987

  •  05-07-2019
  •  | 
  •  

Вопрос

Я нахожусь в ситуации, когда я должен обновить существующую структуру базы данных с varchar на nvarchar с помощью скрипта.Поскольку этот скрипт запускается каждый раз при запуске приложения настройки, я бы предпочел определить, был ли столбец уже изменен на nvarchar, и не выполнять изменение таблицы.Базы данных, которые я должен поддерживать, - это SQL Server 2000, 2005 и 2008.

Это было полезно?

Решение

Следующий запрос должен дать вам то, что вам нужно:

IF EXISTS 
  (SELECT *
   FROM sysobjects syo
   JOIN syscolumns syc ON
     syc.id = syo.id
   JOIN systypes syt ON
     syt.xtype = syc.xtype
   WHERE 
     syt.name = 'nvarchar' AND
     syo.name = 'MY TABLE NAME' AND
     syc.name = 'MY COLUMN NAME')
BEGIN
   ALTER ...
END

Другие советы

Вы можете запустить следующий скрипт, который даст вам набор команд ALTER:

SELECT 'ALTER TABLE ' + isnull(schema_name(syo.id), 'dbo') + '.' +  syo.name 
    + ' ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.length when -1 then 'MAX' 
        ELSE convert(nvarchar(10),syc.length) end + ');'
   FROM sysobjects syo
   JOIN syscolumns syc ON
     syc.id = syo.id
   JOIN systypes syt ON
     syt.xtype = syc.xtype
   WHERE 
     syt.name = 'varchar' 
    and syo.xtype='U'

Однако есть несколько быстрых предостережений для вас. <Ол>

  • Это будет делать только таблицы. Вы захотите отсканировать все свои спроки и функции, чтобы убедиться, что они также изменены на NVARCHAR .
  • Если у вас есть VARCHAR > 4000, вам нужно изменить его на NVARCHAR (MAX)
  • Но это должно быть легко выполнимо с этим шаблоном.

    Если вы хотите, чтобы это выполнялось автоматически, вы можете установить его в предложении WHILE .

    Проблема с ответом Джозефа заключается в том, что после выполнения запросов он изменит поля NOT NULL на NULL . Следующая манипуляция исправляет это:

    SELECT cmd = 'alter table [' + c.table_schema + '].[' + c.table_name 
     + '] alter column [' + c.column_name + '] nvarchar('
     +CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000
           THEN CAST(CHARACTER_MAXIMUM_LENGTH as varchar(10)) ELSE 'max' END+')' 
     + CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END,*
    FROM information_schema.columns c
    WHERE c.data_type='varchar' 
    ORDER BY CHARACTER_MAXIMUM_LENGTH desc
    
      

    Кредиты для ответа Игоря

    Исправлена проблема с пробелом и добавлена схема

    SELECT 'ALTER TABLE [' + isnull(schema_name(syo.object_id), sysc.name) + '].[' +  syo.name 
        + '] ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.max_length when -1 then 'MAX' 
            ELSE convert(nvarchar(10),syc.max_length) end + ');'
       FROM sys.objects syo
       JOIN sys.columns syc ON
         syc.object_id= syo.object_id
       JOIN sys.types syt ON
         syt.system_type_id = syc.system_type_id
        JOIN sys.schemas sysc ON
        syo.schema_id=sysc.schema_id
       WHERE 
         syt.name = 'varchar' 
        and syo.type='U'
    

    Далее обновлено, чтобы исправить замену MAX на -1.

    SELECT cmd = 'ALTER TABLE [' + c.table_schema + '].[' + c.table_name 
     + '] ALTER COLUMN [' + c.column_name + '] NVARCHAR('
     +CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000 THEN 
     CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
     'MAX' ELSE CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) END ELSE 'MAX' END+')' 
     + CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END,*
    FROM information_schema.columns c
    WHERE c.data_type='VARCHAR' 
    ORDER BY CHARACTER_MAXIMUM_LENGTH DESC
    

    Благодарим Ответ Незама

    И еще один для управления значениями по умолчанию:

    SELECT cmd = 
    CASE WHEN name IS NOT NULL THEN
        'ALTER TABLE ' + c.table_name + ' DROP CONSTRAINT ' + d.name + '; ' +
        'ALTER TABLE [' + c.table_schema + '].[' + c.table_name + '] ALTER COLUMN [' + c.column_name + '] ' + 
        'NVARCHAR(' +
        CASE WHEN CHARACTER_MAXIMUM_LENGTH <= 4000 THEN 
            CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
                'MAX' 
            ELSE 
                CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) 
            END 
         ELSE 
            'MAX' 
        END 
        + ')' +
        CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END + '; ' + 
        'ALTER TABLE '+ c.table_name + ' ADD CONSTRAINT ' + d.name +' DEFAULT '+ c.column_default + ' FOR ' + c.column_name + ';'
    ELSE
        'ALTER TABLE [' + c.table_schema + '].[' + c.table_name + '] ALTER COLUMN [' + c.column_name + '] ' +
        'NVARCHAR(' +
        CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000 THEN
            CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN
                'MAX' 
            ELSE 
                CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) 
            END 
        ELSE 
            'MAX' 
        END
        + ')' +
        CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END 
    END,d.name, c.*
    FROM information_schema.columns c
    LEFT OUTER JOIN sys.default_constraints d ON d.parent_object_id = object_id(c.table_name)
    AND d.parent_column_id = columnproperty(object_id(c.table_name), c.column_name, 'ColumnId')
    WHERE c.data_type='VARCHAR' 
    ORDER BY CHARACTER_MAXIMUM_LENGTH DESC
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top