Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Добить скрипт  [new]
xyl!gan
Member

Откуда:
Сообщений: 28
В скрипте вместо [table] я подставляю имя таблицы, для которой его нужно выполнить, при чем в 2х местах.

Как можно вначале задать списик таблиц, а потом прогнать его по этому списку?
DECLARE cursor1 insensitive cursor
for 
SELECT '[table]'as [TblName],
       N'[' + clmns.name + N'] ' +       
      
      CASE WHEN sclmns.name in ('sys', 'dbo')  then '' else '[' + sclmns.name + '].' END +
	   usrt.name + N' ' +
      CASE 
        WHEN (clmns.precision = 0) and (baset.name not in ('XML')) then 
          CASE clmns.max_length 
            WHEN -1 then N'(MAX) ' 
            ELSE N'(' + 
              CASE WHEN baset.name IN (N'nchar', N'nvarchar') then 
                cast((clmns.max_length/2) as nvarchar(20)) 
              else cast(clmns.max_length as nvarchar(20))
              END + N') '
          END
        ELSE N'' 
      END +
      
      -- is NULLABLE
         'NULL ' + 
          
      CASE 
       WHEN clmns.default_object_id = 0 THEN N'' 
       ELSE N'DEFAULT ' + cstr.definition
      END as [Column_Definition]
FROM sys.tables AS tbl 
INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
LEFT OUTER JOIN sys.types AS usrt ON usrt.user_type_id = clmns.user_type_id
LEFT OUTER JOIN sys.types AS baset ON baset.user_type_id = clmns.system_type_id and baset.user_type_id = baset.system_type_id
LEFT OUTER JOIN sys.schemas AS sclmns ON sclmns.schema_id = usrt.schema_id
LEFT OUTER JOIN sys.objects AS d ON d.object_id = clmns.default_object_id
LEFT OUTER JOIN sys.default_constraints AS cstr ON cstr.object_id=d.object_id
 
WHERE
 not exists( -- Исключаем поля, входящие в PK
    select 1 
    from sys.indexes as i
    inner join sys.index_columns as ic on
      i.[object_id] = ic.[object_id] and i.[index_id] = ic.[index_id] 
    where i.[object_id] = tbl.[object_id] and ic.column_id = clmns.column_id
      and i.[is_primary_key] = 1 )
and usrt.name<>'timestamp' and tbl.[object_id] = object_id('[table]')
  order by tblName

declare @table VARCHAR(100),
        @column VARCHAR(100),
        @sql VARCHAR(300)
OPEN cursor1 
FETCH NEXT FROM cursor1 into @table, @column
WHILE @@FETCH_STATUS=0
BEGIN    
    set @sql='alter table '+ @table + ' alter column ' + @column
    exec (@sql)    
    FETCH NEXT FROM cursor1 INTO @table, @column
END
CLOSE cursor1
DEALLOCATE cursor1


Спасибо
6 май 11, 16:20    [10618460]     Ответить | Цитировать Сообщить модератору
 Re: Добить скрипт  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
а в чем тайный смысл данного альтера... я чет не уловил
6 май 11, 16:27    [10618501]     Ответить | Цитировать Сообщить модератору
 Re: Добить скрипт  [new]
xyl!gan
Member

Откуда:
Сообщений: 28
он из not null делает null для всех полей кроме ключа
6 май 11, 16:28    [10618508]     Ответить | Цитировать Сообщить модератору
 Re: Добить скрипт  [new]
xyl!gan
Member

Откуда:
Сообщений: 28
для decimal он пишет неправильное округление, вместо (38,20),
если кто будет пользоватся, что были в курсе.
6 май 11, 16:34    [10618547]     Ответить | Цитировать Сообщить модератору
 Re: Добить скрипт  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
xyl!gan,

скрипт у Вас некорректный. То, что заметил:
  • неправильно оформляется DEFAULT (скобки)
  • все поля получаются NULL. Правильно было бы и NULL и NOT NULL

    По поводу "прогонки" по таблицам: делайте ещё курсор, в которм получайте имя таблицы и т.д., всё это загоняете в переменные,
    а существующий скрипт должен их использовать вместо явного указания.

    На самом деле огрехов намного больше.
    Например, вместо прибавления квадратных скобок к имени таблицы лучше использовать QUOTENAME().
    Констейнтов у таблицы может быть намного больше, чем просто DEFAULT
    PK исключили, но вместо него может быть UNIQUE или просто уникальный индекс.
    timestamp исключили, а с вычисляемыми полями как?
    Для имён объектов есть специальный тип - sysname

    P.S. Детально не разбирался.
  • 6 май 11, 16:42    [10618614]     Ответить | Цитировать Сообщить модератору
     Re: Добить скрипт  [new]
    iap
    Member

    Откуда: Москва
    Сообщений: 47142
    xyl!gan
    он из not null делает null для всех полей кроме ключа
    Ааа! Вот оно что!
    6 май 11, 16:42    [10618622]     Ответить | Цитировать Сообщить модератору
     Re: Добить скрипт  [new]
    Maxx
    Member [скрыт]

    Откуда:
    Сообщений: 24290
    вот и меня сей факт удивил -зачем все поля нулабле делать
    6 май 11, 16:47    [10618650]     Ответить | Цитировать Сообщить модератору
     Re: Добить скрипт  [new]
    xyl!gan
    Member

    Откуда:
    Сообщений: 28
    В скрипте поправил точность для decimal,
    еще вопрос: как можно вызвать этот скрипт для нескольких таблиц, последовательно?

    use [test]
    
    declare @linecount int;
    declare @tName varchar(50) = '[Tax]';
    
    DECLARE cursor1 insensitive cursor
    for 
    SELECT @tName as [TblName],
          -- [type_schema_name]
           N'[' + clmns.name + N'] ' +       
          
          CASE WHEN sclmns.name in ('sys', 'dbo')  then '' else '[' + sclmns.name + '].' END +
    	  -- type_name
           usrt.name + N' ' +
          CASE 
            WHEN (clmns.precision = 0) and (baset.name not in ('XML')) then 
              CASE clmns.max_length 
                WHEN -1 then N'(MAX) ' 
                ELSE N'(' + 
                  CASE
                   WHEN baset.name IN (N'nchar', N'nvarchar') then cast((clmns.max_length/2) as nvarchar(20)) 
                  else cast(clmns.max_length as nvarchar(20))
                  END + N') NULL'
              END
            ELSE N'' 
          END +
          case WHEN baset.name IN (N'decimal') then N'(38,20) NULL ' ELSE N'' 
          END +      
           CASE 
           WHEN clmns.default_object_id = 0 THEN N'' 
           --WHEN d.parent_object_id > 0 THEN N'' 
           ELSE N'DEFAULT ' + cstr.definition
          END as [Column_Definition]
    FROM sys.tables AS tbl 
    INNER JOIN sys.all_columns AS clmns ON clmns.object_id=tbl.object_id
                  LEFT OUTER JOIN sys.types AS usrt ON usrt.user_type_id = clmns.user_type_id
                  LEFT OUTER JOIN sys.types AS baset ON baset.user_type_id = clmns.system_type_id 
                       and baset.user_type_id = baset.system_type_id
                  LEFT OUTER JOIN sys.schemas AS sclmns ON sclmns.schema_id = usrt.schema_id
                  LEFT OUTER JOIN sys.objects AS d ON d.object_id = clmns.default_object_id
                  LEFT OUTER JOIN sys.default_constraints AS cstr ON cstr.object_id=d.object_id
    WHERE
     not exists( -- Исключаем поля, входящие в PK
        select 1 
        from sys.indexes as i
          inner join sys.index_columns as ic on i.[object_id] = ic.[object_id] and i.[index_id] = ic.[index_id] 
        
        where i.[object_id] = tbl.[object_id] and ic.column_id = clmns.column_id and i.[is_primary_key] = 1 )
            and usrt.name<>'timestamp' and usrt.name<>'image' and tbl.[object_id] = object_id(@tName)
      order by TblName
    
    declare @table VARCHAR(100),
            @column VARCHAR(100),
            @sql VARCHAR(300)
    
    OPEN cursor1 
    FETCH NEXT FROM cursor1 into @table, @column
    WHILE @@FETCH_STATUS=0
    BEGIN    
        set @sql='alter table '+ @table + ' alter column ' + @column
        exec (@sql)    
        FETCH NEXT FROM cursor1 INTO @table, @column
    END
    CLOSE cursor1
    DEALLOCATE cursor1
    20 июн 11, 13:21    [10839992]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить