У меня есть некоторый сложный алгоритм, написанный на C # как хранимая процедура CLR. Процедура не является детерминированной (это зависит от текущего времени). Результатом процедуры являются две таблицы.
Я не нашел никакого решения, как обрабатывать мульти-результаты из хранимых процедур в T-SQL. Выполнение этой процедуры является ключевым (процедура вызывается каждые ~ 2 секунды).
Я нашел самый быстрый способ обновления таблиц:
UPDATE [db-table] SET ... SELECT * FROM [clr-func]
Это намного быстрее, чем обновлять db-таблицу из процедуры CLR через ADO.NET.
Я использовал статическое поле для хранения результатов и запроса к ним после выполнения хранимой процедуры clr.
Стек вызовов:
T-SQL proc
-> CLR proc (MyStoredProcedure)
-> T-SQL proc (UpdateDataFromMyStoredProcedure)
-> CLR func (GetFirstResultOfMyStoredProcedure)
-> CLR func (GetSecondResultOfMyStoredProcedure)
Проблема в том, что иногда функции CLR имеют нулевое значение в статическом поле result
, но в процедуре CLR result
не равно нулю. Я обнаружил, что иногда функции CLR вызываются в другом AppDomain, чем процедура CLR. Однако процедура CLR все еще выполняется и может выполнять следующие операции, и исключение не выдается.
Есть ли способ заставить функции CLR вызываться в том же AppDomain, что и "родительская" процедура CLR?
Или есть какой-то другой способ, как достичь моего намерения?
P.S .: Первоначально сложный алгоритм был написан на T-SQL, но производительность была низкой (примерно в 100 раз медленнее, чем алгоритм в C #).
Спасибо!
Упрощенный код:
// T-SQL
CREATE PROC [dbo].[UpdateDataFromMyStoredProcedure] AS BEGIN
UPDATE [dbo].[tblObject]
SET ...
SELECT * FROM [dbo].[GetFirstResultOfMyStoredProcedure]()
UPDATE [dbo].[tblObjectAction]
SET ...
SELECT * FROM [dbo].[GetSecondResultOfMyStoredProcedure]()
END
// ... somewhere else
EXEC [dbo].[MyStoredProcedure]
-
// C#
public class StoredProcedures {
// store for result of "MyStoredProcedure ()"
private static MyStoredProcedureResult result;
[SqlProcedure]
public static int MyStoredProcedure() {
result = null;
result = ComputeComplexAlgorithm();
UpdateDataFromMyStoredProcedure();
result = null;
}
[SqlFunction(...)]
public static IEnumerable GetFirstResultOfMyStoredProcedure() {
return result.First;
}
[SqlFunction(...)]
public static IEnumerable GetSecondResultOfMyStoredProcedure() {
return result.Second;
}
private static void UpdateDataFromMyStoredProcedure() {
using(var cnn = new SqlConnection("context connection=true")) {
using(var cmd = cnn.CreateCommand()) {
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[UpdateDataFromMyStoredProcedure]";
cmd.ExecuteNonQuery();
}
}
}
}