我們有一些問題ANSI_NULLS設置和計算列和我們有一噸的有更改ANSI_NULLS在數據庫設置爲所有存儲過程
SET ANSI_NULLS OFF
存儲過程,我們希望所有這些改變
SET ANSI_NULLS ON
是否有一個簡單的方法來做到這一點還是必須提取所有的SP到一個腳本,改變它,再運行它刪除並重新創建所有水療
我們有一些問題ANSI_NULLS設置和計算列和我們有一噸的有更改ANSI_NULLS在數據庫設置爲所有存儲過程
SET ANSI_NULLS OFF
存儲過程,我們希望所有這些改變
SET ANSI_NULLS ON
是否有一個簡單的方法來做到這一點還是必須提取所有的SP到一個腳本,改變它,再運行它刪除並重新創建所有水療
您必須腳本編寫所有過程,然後使用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: How to generate object scripts without DMO/SMO?
代碼,但通常我只會用企業管理,開始於頂部存儲過程列表:
凡我剪貼板包含:
SET ANSI_NULLS ON
GO
如果你不幸被SSMS卡住了,那麼你就是那個POS,IIRC的SOL。 TWSS。
到目前爲止電子最簡單的方法是腳本s'procs,運行查找和替換命令,然後再次運行proc定義。
當你有數百個存儲過程時,這不是最簡單的方法。 選擇OBJECT_NAME(OBJECT_ID)的名稱,定義代碼 從sys.all_sql_modules 其中OBJECTPROPERTY([OBJECT_ID],「IsProcedure: – Suncat2000 2017-06-02 14:29:13
我們使用的解決方案是張貼伊恩現在我們有一個自動化的程序來解決這個問題。
這裏是我們用來重建所有從數據庫中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; }
}
}
只是想拋出一個警告在那裏。我無法想象爲什麼你的ansi_nulls會爲你所有的SP啓動,但是如果它們中的任何一個都以任何方式將NULL與NULL進行比較(並且可能會有很多不同的方式),當你改變時你的結果會不同該設置。我建議在安全的環境中進行一些嚴格的迴歸測試。
@TG:感謝您的警告,所有這些存儲過程都是自動生成的CRUD操作。我們擁有所有SP,因爲我們在模板sql中保留了SET ANSI_NULLS OFF。程序非常簡單,我們不會涉及這個問題。 – MarcosMeli 2010-01-29 05:25:43
我明白了 - 這很有道理。如果您的代碼生成器具有該ansi_nulls設置,那麼當然它們都會以這種方式結束。那麼可能任何手動創建的SP都沒有關閉ansi_nulls。如果任何生成的SP在可空列上加入JOIN,我想只有潛在的「gottcha」纔會出現。但事實並非如此。繼續 :) – 2010-01-29 13:32:44
由於一噸,我會用這個SQL來獲取所有失敗的SP及其代碼走那條路')= 1 and uses_ansi_nulls = 0 – MarcosMeli 2010-01-27 14:37:59
我剛剛添加了C#代碼來重新創建所有sps :)我們無法手動完成,因爲我們有8個數據庫,每個數據庫都有近500個,所以感謝您指出如何自動化過程。 – MarcosMeli 2010-01-27 15:24:53
編輯的僞代碼:在連接上設置ansi_nulls選項一次 - 因爲批處理中必須單獨使用「CREATE PROC」。 – 2010-01-27 18:51:34