我们在ANSI_NULLS设置和计算列方面存在一些问题,我们有大量的存储过程
SET ANSI_NULLS OFF
我们希望将它们全部更改为
SET ANSI_NULLS ON
是否有一种简单的方法可以做到这一点,或者我必须将所有SP提取到脚本中,更改它并再次运行它以删除并重新创建所有SPa
答案 0 :(得分:4)
您必须编写所有过程的脚本,然后使用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 Server: How to generate object scripts without DMO/SMO?
上以编程方式获取存储过程的SQL的代码但通常我只会使用企业管理器,从存储过程列表的顶部开始:
我的剪贴板包含:
SET ANSI_NULLS ON
GO
如果你不幸被SSMS困住,那么你就是那个POS,IIRC的SOL。 TWSS。
答案 1 :(得分:3)
我们使用的解决方案是由 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 :(得分:2)
只想在那里发出警告。我无法想象为什么你的所有SP都启动了ansi_nulls,但是如果他们中的任何一个指望以任何方式与NULL进行比较(并且可能会有很多不同的方式),那么当你改变时你的结果会有所不同那个设定。我建议在安全的环境中进行一些严格的回归测试。
答案 3 :(得分:1)
到目前为止,最简单的方法是编写s'procs脚本,运行find和replace命令,然后再次运行proc定义。