Измените параметр ANSI_NULLS для всех хранимых процедур в базе данных. - PullRequest
5 голосов
/ 27 января 2010

У нас есть некоторые проблемы с настройкой ANSI_NULLS и вычисляемыми столбцами, и у нас есть тонна хранимых процедур, которые имеют

SET ANSI_NULLS OFF

Мы хотим изменить их все на

SET ANSI_NULLS ON

Есть ли простой способ сделать это, или я должен извлечь все SP в сценарий, изменить его и запустить снова, чтобы удалить и воссоздать все SPa

Ответы [ 4 ]

4 голосов
/ 27 января 2010

Вы должны записать все процедуры и заново создать их с включенным ANSI_NULLS.

Если бы у меня было много , я мог бы добавить функцию в мое клиентское приложение.

псевдокод:

procedure FixAllStoredProcedureAnsiNullness(connection)
{
   Strings spNames = GetStoredProcedureNames(connection);

   foreach spName in spNames
   {
       String sql = GetStoredProcedureSQL(connection, spName);

       //turn on option for remainder of connection
       connection.ExecuteNoRecords("SET ANSI_NULLS ON"); 

       BeginTransaction(connection);
       try
          connection.ExecuteNoRecords("DROP PROCEDURE "+spName);
          connection.ExecuteNoRecords(sql);
          CommitTranasction(connection);
       except
          RollbackTransaction(connection);
          raise;
       end;
   }
}

У меня был код, как программно получить SQL хранимой процедуры на SQL Server: Как генерировать объектные сценарии без DMO / SMO?

Но обычно я просто использую Enterprise Manager , начиная с верхней части списка хранимых процедур:

  1. Возвращение
  2. Ctrl + Главная
  3. Ctrl + * +1031 * V * ** 1033 тысяча тридцать-дв *
  4. Нажмите OK
  5. Авансовый
  6. Перейти к 1

Где мой буфер обмена содержит:

SET ANSI_NULLS ON
GO

Если вы достаточно неудачливы, чтобы застрять в SSMS, то вы SOL с этим POS, IIRC. TWSS.

3 голосов
/ 27 января 2010

Решение, которое мы использовали, было опубликовано Ian , и теперь у нас есть автоматизированная процедура для решения проблемы.

Вот окончательный код, который мы используем для воссоздания всех SP из базы данных:

public static class AnsiNullsManager
{

    public static void ReCreateAllStoredProcedures(SqlConnection connection, bool ansiNullsOn)
    {
        var sql =
            @"select object_name(sys.all_sql_modules.object_id) as Name, definition as Code
                from sys.all_sql_modules inner join sys.objects ON 
                sys.all_sql_modules.object_id = sys.objects.object_id
                where objectproperty(sys.all_sql_modules.object_id, 'IsProcedure') = 1 AND is_ms_shipped = 0 and uses_ansi_nulls = " +
            (ansiNullsOn ? "0" : "1") +
            "ORDER BY Name ";

        if (connection.State == ConnectionState.Closed)
            connection.Open();

        var sps = new List<SpObject>();

        var cmd = connection.CreateCommand();
        cmd.CommandText = sql;

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                sps.Add(new SpObject(reader.GetString(0), reader.GetString(1)));
            }
        }

        var cmdSetAnsiNulls = connection.CreateCommand();
        cmdSetAnsiNulls.CommandText = "SET ANSI_NULLS " + (ansiNullsOn ? "ON" : "OFF") + ";";
        cmdSetAnsiNulls.ExecuteNonQuery();

        foreach (var sp in sps)
        {
            var trans = connection.BeginTransaction();

            try
            {

                var cmdDrop = connection.CreateCommand();
                cmdDrop.CommandText = "DROP PROCEDURE " + sp.Name;
                cmdDrop.Transaction = trans;
                cmdDrop.ExecuteNonQuery();



                var cmdReCreate = connection.CreateCommand();
                cmdReCreate.CommandText = sp.Code;
                cmdReCreate.Transaction = trans;
                cmdReCreate.ExecuteNonQuery();
                trans.Commit();

            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

    }

    private class SpObject
    {
        public SpObject(string name, string code)
        {
            Name = name;
            Code = code;
        }

        public string Name { get; private set; }
        public string Code { get; private set; }
    }

}
2 голосов
/ 29 января 2010

Просто хотел добавить предупреждение. Я не могу себе представить, почему вы установили ansi_nulls для ВСЕХ своих SP, но если какой-либо из них рассчитывал на сравнение с NULL каким-либо образом (и может быть много разных способов), ваши результаты будут отличаться при изменении эта настройка. Я рекомендую провести тщательное регрессионное тестирование в безопасной среде.

1 голос
/ 27 января 2010

На сегодняшний день самый простой способ - написать скрипт s'procs, выполнить команду find и replace, а затем снова запустить определения proc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...