Сообщений 0 Оценка 192 [+1/-0] Оценить |
Основной понятием при работе с СУБД является таблица. Таблица представляет собой набор записей одинакового типа. Запись таблицы состоит из полей скаляных (базовых) типов.
Использование скаляных типов не ограничивается таблицами. Хранимые процедуры также могут принимать и возвращать скалярные типы. Причём возвращать их могут различными путями. BLToolkit поддерживает несколько вариантов: через IDataReader, выходной параметр или возвращаемое значение.
ПРИМЕЧАНИЕ BLToolkit не навязывает Вам пути работы с базой данных. Вы можете использовать тот способ, который наиболее удобен. |
Разные СУБД поддерживают различные наборы скалярных типов, но все поддерживают как минимум следующие: строки, числа, дата и время. СУБД Oracle поддерживает также массивы скалярных типов.
При вызове хранимой процедуры или запроса на сервер можно передать нужное количество параметров. Все они должны быть скалярного типа, известного серверу.
Задать параметры можно либо явно, при вызвав метод DbManager.Parameter() либо неявно, просто передав значение параметра в DbManager.SetCommand/SetSpCommand:
using (DbManager db = new DbManager()) { // Привязка по имени db.SetSpCommand("SomeSP").Parameter(“Foo”, 12345); // Привязка по порядку db.SetSpCommand("SomeSP", 12345); } |
Имена и типы параметров запрашиваются у сервера, если провайдер поддерживает такую возможность.
Ещё проще передать параметры при помощи DataAccessor’а:
public abstract class TestAccessor : DataAccessor { public abstract void SomeSP(int Foo); } // … TestAccessor ta = TestAccessor.CreateInstance(); ta.SomeSP(12345); |
Т.е. вызов ta.SomeSP магическим образом превращается в вызов соответствующей процедуры на сервере! К тому же с проверкой типов на этапе компиляции.
Получить данные скалярного типа от сервера не многим сложнее. Но здесь имеется несколько вариантов:
Первый и второй способ можно расширить, допустив что возвращается несколько полей или параметров и используется одно из значений, а остальные игнорируются.
Выходые параметры, как и входные можно задать явно:
using (DbManager db = new DbManager()) { db.SetSpCommand("SomeSP").OutputParameter(“Foo”); } |
После выполнения запроса можно обратиться к свойству Value нужного параметра для получения значения, возвращённого сервером.
Для получения единственного значения удобнее использовать метод DbManager.ExecuteScalar. Этот метод существует в двух вариантах. Первый вариант без параметров и реализует базовый способ, второй вариант позволяет явно указать, каким образом сервер возвращает значение:
using (DbManager db = new DbManager()) { // Значение 1-го поля первой записи. int scalarValue = db.SetSpCommand("…").ExecuteScalar<int>(); // Значение 2-го поля первой записи scalarValue = db.SetSpCommand("…").ExecuteScalar<int>(ScalarSourceType.DataReader, 1); // Значение 1-го выходного параметра scalarValue = db.SetSpCommand("…").ExecuteScalar<int>(ScalarSourceType. OutputParameter); // Значение 2-го выходного параметра scalarValue = db.SetSpCommand("…").ExecuteScalar<int>(ScalarSourceType. OutputParameter, 1); // Возвращаемое значение функции scalarValue = db.SetSpCommand("…").ExecuteScalar<int>(ScalarSourceType. ReturnValue); } |
В качестве бесплатного приложения ExecuteScalar может возвращать количество обработанных при помощи ExecuteNonQuery записей:
using (DbManager db = new DbManager()) { // Количество обработанных записей int affected = db.SetSpCommand("…").ExecuteScalar<int>(ScalarSourceType. AffectedRows); // Тоже самое affected = db.SetSpCommand("…").ExecuteNonQuery(); } |
Этот вариант добавлен для упрощения реализации DataAccessBuilder’а. Здесь все точно так же, но вместо параметра используется одноименный атрибут:
public abstract class TestAccessor : DataAccessor { // Явное использование выходных параметров public abstract void Scalar_OutputParameterRegression(out int outputInt, out string outputString); // Значение 1-го поля первой записи. public abstract int Scalar_Regression(); // Значение 1-го поля первой записи. [ScalarSource(ScalarSourceType.DataReader)] public abstract int Scalar_DataReader(); // Значение 2-го поля первой записи. [ScalarSource(ScalarSourceType.DataReader, 1)] public abstract string Scalar_DataReader2(); // Значение 1-го выходного параметра [ScalarSource(ScalarSourceType.OutputParameter)] public abstract int Scalar_OutputParameter(); // Значение 2-го выходного параметра [ScalarSource(ScalarSourceType.OutputParameter, 1)] public abstract string Scalar_OutputParameter2(); // Возвращаемое значение функции [ScalarSource(ScalarSourceType.ReturnValue)] public abstract int Scalar_ReturnParameter(); // Количество обработанных записей [ScalarSource(ScalarSourceType.AffectedRows)] public abstract int Scalar_AffectedRows(); } |
Использование DataAccessor’а позволяет задать один раз способ получения значения и больше не задумываться над этим вопросом.
Код хранимых процедур, использованных при написании этой статьи.
Код для MSSQL ServerСообщений 0 Оценка 192 [+1/-0] Оценить |