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

Откуда:
Сообщений: 162
Можно ли в sql2005 сгенерировать скрипт по alter для более чем одной процедуры за 1 раз?
11 янв 10, 16:07    [8166339]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
PokeMan
Member

Откуда: MOSKAU
Сообщений: 312
Тут для триггеров обсуждалось. Предполагаю, что можно и для процедур.

SELECT
  OBJECT_DEFINITION(o.object_id) +'
GO
  '
FROM sys.objects o
WHERE [type] = 'P'

Дальше только alter прикрутить ...
12 янв 10, 11:29    [8169865]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
iap
Member

Откуда: Москва
Сообщений: 46983
PokeMan
Тут для триггеров обсуждалось. Предполагаю, что можно и для процедур.

SELECT
  OBJECT_DEFINITION(o.object_id) +'
GO
  '
FROM sys.objects o
WHERE [type] = 'P'

Дальше только alter прикрутить ...
К сожалению, в общем случае задача нетривиальная.
Ведь надо заменить CREATE на ALTER, но CREATE вполне может быть, например, в комментарии
перед командой CREATE PROC. Выяснить программно, находится ли заменяемое слово CREATE в
комментарии, не так уж и просто. Пример:
USE tempdb;
SET NOCOUNT ON;
IF OBJECT_ID(N'P','P') IS NOT NULL DROP PROC P;
GO
/*CREATE PROCEDURE P*/
CREATE PROCEDURE P AS RETURN;
GO

SELECT OBJECT_DEFINITION(OBJECT_ID(N'P','P'))
GO

/*CREATE PROCEDURE P*/
ALTER PROCEDURE P AS RETURN;
GO

SELECT OBJECT_DEFINITION(OBJECT_ID(N'P','P'))
GO
12 янв 10, 12:25    [8170242]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
PokeMan
Member

Откуда: MOSKAU
Сообщений: 312
То iap, факт.

Как вариант можно сделать DROP -> CREATE.
Или синтаксический анализ (Студия, к примеру, как раз его и производит для того чтобы сформировать ALTER).
12 янв 10, 12:37    [8170318]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
Crimean
Member

Откуда:
Сообщений: 13148
PokeMan
То iap, факт.

Как вариант можно сделать DROP -> CREATE.
Или синтаксический анализ (Студия, к примеру, как раз его и производит для того чтобы сформировать ALTER).


при DROP / CREATE надо запариваться с правами. а при ALTER - нет. так что смысл делать именно ALTER как раз есть
опять же, отправлю в фак, там есть подборка ссылочек на решения по данному вопросу :)
12 янв 10, 14:24    [8171231]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31367
Crimean
при DROP / CREATE надо запариваться с правами. а при ALTER - нет.
Ещё нужно разбираться с WITH APPEND
12 янв 10, 15:09    [8171692]     Ответить | Цитировать Сообщить модератору
 Re: alter процедур  [new]
DeColo®es
Member

Откуда: Москва
Сообщений: 5499
Блог
alexeyvg
Crimean
при DROP / CREATE надо запариваться с правами. а при ALTER - нет.
Ещё нужно разбираться с WITH APPEND
И с параметрами SET ANSI_NULLS & QUOTED_IDENTIFIER

Пример, как менять CREATE на ALTER тут (см. процедуру _Context.UpdateProcedures).
Там нет "защиты" от CREATE PROCEDURE в комментариях, но это относительно несложно сделать на T-SQL.
12 янв 10, 20:51    [8174084]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: alter процедур  [new]
лолл
Member

Откуда:
Сообщений: 450
iap,

Была такая задача по созданию скриптера, но мешали комментарии. Можно решить на чистом T-SQL. Прототип для скалярной функции:

+
DECLARE
  @Text       NVarChar(MAX), -- Где ищем
  @SubString  NVarChar(4000), -- Что ищем
  @Pos        Int = 1 -- С какого символа начинаем

SET @Text = '\
/*CREATE PROCEDURE P1*/
--CREATE PROCEDURE P2
CREATE PROCEDURE P4 AS RETURN;
GO
'

SET @SubString = 'CREATE'

  DECLARE
    @TextLen      Int = LEN(@Text),
    @SubStringLen Int = LEN(@SubString),

    @C1Begin      NVarChar(2) = N'/*',
    @C1End        NVarChar(2) = N'*/',

    @C2Begin      NVarChar(2) = N'--',
    @C2End        NVarChar(2) = NChar(13),

    @C1BeginI     Int,
    @C2BeginI     Int,
    @C1EndI       Int,
    @SubStringI   Int,
    
    @C1Count      Int = 0


  WHILE @Pos > 0 AND @Pos <= @TextLen
  BEGIN

    SET @C1BeginI   = CHARINDEX(@C1Begin, @Text, @Pos)
    SET @C2BeginI   = CHARINDEX(@C2Begin, @Text, @Pos)
    SET @C1EndI     = CHARINDEX(@C1End, @Text, @Pos)
    SET @SubStringI = CHARINDEX(@SubString, @Text, @Pos) 

    PRINT 'I          =' + CAST(@Pos AS NVARCHAR)
    PRINT '@C1Count   =' + CAST(@C1Count AS NVARCHAR(60))
    PRINT 'C1BeginI   =' + CAST(CHARINDEX(@C1Begin, @Text, @Pos) AS NVARCHAR(60))
    PRINT 'C2BeginI   =' + CAST(CHARINDEX(@C2Begin, @Text, @Pos) AS NVARCHAR(60))
    PRINT 'C1EndI     =' + CAST(CHARINDEX(@C1End, @Text, @Pos) AS NVARCHAR(60))
    PRINT 'SubStringI =' + CAST(CHARINDEX(@SubString, @Text, @Pos)  AS NVARCHAR(60))

    IF @C1Count = 0
       AND
       (
        @SubStringI <= 0
        OR
        (@SubStringI < @C1BeginI OR @C1BeginI = 0)
        AND
        (@SubStringI < @C2BeginI OR @C2BeginI = 0)
        AND
        (@SubStringI < @C1EndI OR @C1EndI = 0)
       )
    BEGIN
      PRINT 'Либо строку не нашли вообще, либо нашли и она не закомментирована'
      -- Либо строку не нашли вообще, либо нашли до комментариев
      SET @Pos = @SubStringI;
      BREAK;
    END

    -- Строка есть где-то за комментариями, начинаем колдовать

    -- Начался комментарий C1
    IF @C1BeginI > 0 AND @C1BeginI < @SubStringI AND (@C1BeginI < @C2BeginI OR @C2BeginI = 0)
    BEGIN
      PRINT '/*'

      SET @C1Count += 1;

      SET @Pos = @C1BeginI + LEN(@C1Begin);
      CONTINUE;
    END

    -- Закончился комментарий C1
    IF @C1EndI > 0 AND (@C1EndI < @C2BeginI OR @C2BeginI = 0 OR @C1Count > 0)
    BEGIN
      PRINT '*/'
      IF @C1Count > 0
        SET @C1Count -= 1;

      SET @Pos = @C1EndI + LEN(@C1End);
      CONTINUE;
    END

    -- Начался комментарий C2
    IF @C2BeginI > 0 AND @C2BeginI < @SubStringI AND (@C2BeginI < @C1BeginI OR @C1BeginI = 0) AND @C1Count = 0
    BEGIN
      PRINT '--'
      SET @Pos = CHARINDEX(@C2End, @Text, @C2BeginI + LEN(@C2Begin)); -- Перейти сразу в конец!
      IF @Pos > 0
        CONTINUE;
    END    

    SET @Pos = 0;
    BREAK;
  END

  IF @TextLen = 0
    SET @Pos = 0;

  SELECT @Pos, SUBSTRING(@Text, @Pos, 19);


Останется только учесть, что между CREATE и PROCEDURE могут быть пробелы или другие комментарии, а так же сокращенный вариант CREATE PROC (ну и прочие объекты по аналогии)

Сообщение было отредактировано: 2 мар 19, 00:58
2 мар 19, 00:41    [21823185]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить