C# — Определение наличия хранимой процедуры

Я написал расширение DbContext, чтобы попытаться определить, существует ли хранимая процедура в связанной с ней базе данных.

    public static bool StoredProcedureExists(this DbContext input, string name)
    {
        int exists = input.Database.ExecuteSqlCommand(string.Format("SELECT TOP 1 * FROM [sys].[objects] WHERE [type_desc] = 'SQL_STORED_PROCEDURE' AND [name] = '{0}';", name));

        //return true; // if it exists, else false
    }

Проблема в том, что независимо от того, существует хранимая процедура name или нет, моя переменная exists (возвращенная из ExecSqlCommand) всегда содержит '-1'. Поэтому я не могу определить, находится ли хранимая процедура в базе данных или нет.

Выполнение сгенерированного запроса в SQL Server Management Studio работает должным образом, возвращая одну строку, если хранимая процедура существует, и никаких строк, если нет.

Есть ли у кого-нибудь идеи о том, как этого добиться (программно определить, существует ли хранимая процедура с базой данных)?

Спасибо, Роб.


person Rob L    schedule 03.09.2013    source источник
comment
Я настоятельно рекомендую использовать более сфокусированные представления каталога и по возможности избегать sys.objects. Ваш запрос будет легче читать и понимать, если вы используете SELECT .. FROM sys.procedures WHERE ....   -  person marc_s    schedule 04.09.2013


Ответы (2)


Спасибо за помощь... В итоге у меня получилось так:

    public static bool StoredProcedureExists(this DbContext input, string name)
    {
        var query = input.Database.SqlQuery(
            typeof(int), 
            string.Format("SELECT COUNT(*) FROM [sys].[objects] WHERE [type_desc] = 'SQL_STORED_PROCEDURE' AND [name] = '{0}';", name), 
            new object[] {});

        int exists = query.Cast<int>()
            .Single();

        return (exists > 0);
    }
person Rob L    schedule 04.09.2013

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

               SELECT [schema] = OBJECT_SCHEMA_NAME([object_id]),
                       name
               FROM sys.procedures;
               WHERE name = @param_proc_name

и вызовите эту процедуру из своего кода перед вашей логикой.

person Basem Sayej    schedule 04.09.2013
comment
Спасибо за ответ. Я пытаюсь избежать каких-либо зависимостей. Я планирую сделать его как можно более универсальным для своей базовой библиотеки. - person Rob L; 04.09.2013
comment
я не знаю, правильно ли я здесь или нет, но executesqlcommand вам здесь не поможет, поскольку он возвращает результат, возвращаемый базой данных после выполнения команды. поскольку нет ни выходных параметров, ни возвращаемого целого числа, этот оператор ведет себя так, как ожидалось. попробуйте выполнить скалярную команду. - person Basem Sayej; 04.09.2013