Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Гостевая книга ... 65535
Содержание сайт... 65535
Вызов хранимых ... 65535
Эмулятор микроп... 65535
Бип из системно... 58490
Invision Power ... 57583
Организация зап... 57365
Модуль Forms 56484
Создание отчето... 55030
Приложение «Про... 54668
Подключение Mic... 54522
Оператор выбора... 54289
ТЕХНОЛОГИИ ДОСТ... 51067
Программируемая... 47651
Имитационное мо... 46810
Пример работы с... 46787
21 ошибка прогр... 41851
Реклама
Сейчас на сайте
Гостей: 4
На сайте нет зарегистрированных пользователей

Пользователей: 13,008
новичок: lyuscherbakova19
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Диплом RSA, ЭЦП, сертификаты, шифрование на C#
Лабораторная работа по динамическим спискам на Turbo Pascal (перемещение...
Моделирование работы обрабатывающего участка цеха в GPSS

Реклама

Вызов хранимых процедур из приложения с использованием технологии ADO (Delphi + Microsoft SQL Server)


Компонент для вызова ХП


Для вызова ХП в технологии ADO используется компонент TADOStoredProc. Компонент позволяет передать входные параметры в вызываемую ХП, запустить на выполнение ХП на сервере БД, а также получить результаты выполнения ХП в виде выходных параметров, кода ошибки или результирующего набора данных.
В некоторых случаях можно использовать для вызова ХП и компоненты TADOQuery или TADOCommand, вводя в поля SQL или CommandText соответствующий оператор запуска процедуры (для MS SQL Server – это оператор EXEC). Однако такой подход не позволяет получить значения выходных параметров процедур и кода ошибки. Кроме того, при таком способе приходится учитывать особенности вызова ХП для каждой конкретной СУБД, в то время как компонент TADOStoredProc автоматически учитывает эти особенности.
Также как и компоненты TADOTable и TADOQuery, компонент TADOStoredProc является наследником базового класса TDataSet, т.е. является разновидностью набора данных. В связи с этим, ряд свойств и методов, присутствующих в компонентах TADOTable и TADOQuery, имеется и у компонента TADOStoredProc. К таковым, в частности, относятся:
Connection – ссылка на компонент TADOConnection для подключения к БД, в которой хранится ХП;
Active – при задании свойству значения true выполняет ХП и открывает набор данных, возвращаемый ХП. Не возвращает значения выходных параметров.
Однако есть и некоторые новые свойства и методы. К таким свойствам относятся:
StoredProcName – имя ХП;
• Parameters – массив входных и выходных параметров ХП;
К основным методам относятся:
ExecProc – выполняет ХП. Позволяет вернуть значения выходных параметров, но не возвращает результирующий набор данных.
Рассмотрим простейший пример использования компонента TADOStoredProc. Создадим в контексте БД Supply хранимую процедуру sp1, которая уменьшает цену всех товаров на 20%. Исходный текст ХП:
CREATE PROCEDURE sp1
AS
UPDATE Товары
SET Цена = Цена * 0.8
GO



Создадим приложение, позволяющее выполнить хранимую процедуру. Для этого необходимо:
• поместить на форму компоненты TADOConnection, TADOTable, TADOStoredProc, TDataSource, TDBGrid и TButton, задать им соответствующие имена, например, ADOConnection, ADOTableGoods, ADOStoredProc1, DataSourceGoods, DBGridGoods, ButtonExecSP1;
• настроить соединение с БД с помощью компонента ADOConnection (см. предыдущую работу);
• связать компоненты между собой. Для этого задать с помощью Object Inspector следующие свойства компонент:
DBGridGoods.DataSource = DataSourceGoods (связать сетку с источником);
DataSourceGoods.DataSet = ADOTableGoods (связать источник с таблицей);
ADOTableGoods.Connection = ADOConnection (связать таблицу с компонентом соединения с БД);
• задать свойство TableName компонента ADOTableGoods, выбрав имя таблицы, которая обновляется хранимой процедурой, т.е. Товары;
• разрешить «живые данные» для компонента ADOTableGoods, установив его свойство Active = true;
• связать компонент ADOStoredProc1 компонентом ADOConnection;
• задать свойство ProcedureName компонента StoredProc1, выбрав имя хранимой процедуры sp1;
• для кнопки ButtonExecSP1 написать обработчик, который при ее нажатии будет выполнять хранимую процедуру, и обновлять данные таблицы Товары в окне DBGridGoods.
Пример кода для Borland Delphi:
...
ADOStoredProc1.ExecProc;
ADOTableGoods.Refresh;
...




Метод Refresh позволяет обновить набор данных. Он может применяться к любому компоненту, наследующему свойства от TDataSet. В нашем случае он позволяет увидеть изменения, внесенные в таблицу Товары процедурой sp1.
• запустить приложение и убедиться в правильном выполнении хранимой процедуры (рисунок 1).



При нажатии на кнопку ButtonExecSP1 ХП sp1 выполняется, уменьшая цену всех товаров на 20%. Результаты обновления записей таблицы товаров можно наблюдать в сетке DBGridGoods.
Как уже отмечалось, компонент TADOStoredProc может вернуть в качестве результатов выполнения ХП набор данных. Для этого требуется вставить в тело ХП оператор SELECT. Результат выполнения оператора SELECT и будет результирующим набором данных.
Таким образом, можно рассмотренную выше задачу решить и другим способом. Вместо использования отдельного компонента TADOTable для просмотра результатов выполнения ХП будем использовать сам компонент TADOStoredProc. Для этого внесем в клиентское приложение следующие изменения:
• изменим процедуру sp1, добавив в нее оператор SELECT, возвращающий все записи таблицы Товары:

ALTER PROCEDURE sp1
AS
UPDATE Товары
SET Цена = Цена * 0.8
SELECT * FROM Товары
GO



• удалим компонент ADOTableGoods;
• компонент DataSourceGoods привяжем к компоненту ADOStoredProcSP1:
DataSourceGoods–>DataSet = ADOStoredProc1;



• обработчик для кнопки ButtonExecSP1 изменим следующим образом:
// Закрыть набор данных
ADOStoredProc1.Active := false;
// Выполнить ХП и открыть набор данных
ADOStoredProc1.Active := true;



Обратите внимание, что использовать метод ExecProc в данном случае нельзя, т.к. он не позволяет открыть результирующий набор данных. Если обработчик будет написан так, как приведено ниже, содержимое таблицы Товары не удастся увидеть в сетке:
...
ADOStoredProc1.ExecProc;
...



• откомпилируем и запустим проект. После нажатия на кнопку ButtonExecSP1 в окне приложения появятся результаты изменения записей таблицы Товары.

Особенности передачи параметров


Достаточно часто в ХП используются параметры. Они бывают следующих видов:
• входные – используются для задания исходных данных, необходимых для работы процедуры;
выходные – возвращают результаты выполнения процедуры;
входные-выходные – могут использоваться одновременно и для задания исходных данных, и для возврата результатов выполнения процедуры.
код ошибки – возвращает целое число в диапазоне 0..255, позволяющее узнать, насколько успешно выполнена процедура. Если ошибок в выполнении ХП нет, обычно возвращается код 0. При наличии ошибок возвращаются те или иные коды отличные от нуля.
Назначение каждого кода приводится в описании каждой конкретной ХП.
Для работы с параметрами компонент TADOStoredProc имеет специальное свойство Parameters типа T Parameters, представляющее собой массив параметров. При этом свойство Parameters.Count содержит количество параметров процедуры.
На этапе разработки приложения при выборе требуемой процедуры с помощью свойства ProcedureName происходит автоматическое определение количества, названий, типов и видов параметров ХП. Соответственно, массив параметров Parameters автоматически заполняется.
Тип TParameters среди прочих содержит полезное свойство ParamValues, позволяющее обращаться к требуемому параметру по имени. Например:
ADOStoredProc2.Parameters.ParamValues['@Name'] := EditName.Text;



Здесь параметру с именем @Name присваивается значение, из поля ввода с именем EditName. Свойство ParamValues относится к вариантному типу, который позволяет автоматически преобразовывать к нужному типу строковые и числовые типы данных.
Рассмотрим пример, показывающий, каким образом могут передаваться входные параметры. Создадим процедуру sp2, позволяющую добавить запись о новом товаре в таблицу Товар. Исходный текст процедуры приведен ниже.

CREATE PROCEDURE sp2 (
@Code int, -- Код товара
@Name varchar(20), -- Наименование
@Firm varchar(20), -- Производитель
@Price int -- Цена
)
AS
-- Добавить новый товар
INSERT INTO Товары (КодТовара, Наименование, Производитель, Цена)
VALUES (@Code, @Name, @Firm, @Price)
GO



В процедуре используются четыре входных параметра. Обратите внимание, что для поля типа varchar необходимо явно указать длину поля. Например, varchar(20). Если длину поля не указать, то по умолчанию длина поля будет считаться равной 1, т.е. все равно, что написать varchar(1).
Создадим клиентское приложение, вызывающее ХП. Для этого необходимо:
• поместить на форму компоненты TADOConnection, TADOTable, TADOStoredProc, TDataSource, TDBGrid, TButton, задать им соответствующие имена, например, ADOConnection, ADOTableGoods, ADOStoredProc2, DataSourceGoods, DBGridGoods, ButtonExecSP2. Для ввода значений параметров также разместить четыре компонента TEdit (с именами TEditCode, TEditName, TEditFirm, TEditPrice). Изображение формы приведено на рисунке 2;
• настроить соединение с БД с помощью компонента ADOConnection (см. предыдущую работу);
• связать компоненты между собой по аналогии с предыдущим примером;
• для кнопки ButtonExecSP2 написать обработчик, который при ее нажатии будет передавать введенные исходные данные в хранимую процедуру, выполнять ее и обновлять данные таблицы Товары в сетке DBGridGoods.
Пример кода для Borland Delphi:
...
// Задать параметры процедуры
// Код товара
ADOStoredProc2. Parameters.ParamValues['@Code'] := EditCode.Text;
// Название товара
ADOStoredProc2. Parameters.ParamValues['@Name'] := EditName.Text;
// Производитель
ADOStoredProc2. Parameters.ParamValues['@Firm'] := EditFirm.Text;
// Цена
ADOStoredProc2.Parameters.ParamValues['@Price']:= EditPrice.Text;
// Выполнить процедуру
ADOStoredProc2.ExecProc;
// Обновить набор данных
ADOTableGoods.Refresh;
...



В приведенном примере сначала считываются значения из полей ввода и присваиваются соответствующим параметрам, затем процедура запускается на выполнение с помощью метода ExecProc.
• запустить приложение и убедиться в правильном выполнении хранимой процедуры. При нажатии на кнопку Выполнить в таблицу Товары будет добавляться новая запись со значениями атрибутов, указанными в соответствующих полях ввода. Новая запись должна сразу же появиться в сетке.



Теперь рассмотрим пример процедуры, использующей выходные параметры. Создадим процедуру, позволяющую узнать количество записей в таблице Поставки. Исходный текст процедуры приведен ниже.
CREATE PROCEDURE sp3 (@s int output) AS
SELECT @s = COUNT(*)
FROM Поставки
GO




В процедуре используется один выходной параметр @s, предназначенный для возврата найденного количества записей. Обратите внимание, что выходной параметр должен выть описан с помощью ключевого слова OUTPUT. С помощью операторов SELECT или SET выходному параметру должно быть присвоено результирующее значение.
Напомним, что программе на языке T-SQL хранимая процедура с выходными параметрами вызывается следующим образом:
-- Описать переменную,
-- в которую будет помещено значение выходного параметра
DECLARE @TotalCount INT
-- Выполнить процедуру
EXEC sp3 @TotalCount OUTPUT
-- Вывести результат на экран
PRINT @TotalCount




Создадим клиентское приложение, вызывающее ХП. Для этого необходимо:
• поместить на форму компоненты TADOConnection, TADOTable, TADOStoredProc, TDataSource, TDBGrid, TButton, TEdit и задать им соответствующие имена, например, ADOConnection, ADOTableSupply, ADOStoredProc3, DataSourceSupply, DBGridSupply, ButtonExecSP3, EditTotalCount.;
• настроить соединение с БД с помощью компонента ADOConnection (см. предыдущую работу);
• связать компоненты между собой по аналогии с предыдущими примерами;
• для кнопки ButtonExecSP3 написать обработчик, который при ее нажатии будет выполнять хранимую процедуру и передавать значение выходного параметра в поле EditTotalCount.
Пример кода для Borland Delphi:
...
// Выполнить процедуру
ADOStoredProc3.ExecProc;
// Считать значение выходного параметра
EditTotalCount.Text := ADOStoredProc3.Parameters.ParamValues['@s'];
...



• запустить приложение и убедиться в правильном выполнении хранимой процедуры. При нажатии на кнопку Выполнить в поле ввода будет отображаться количество записей в таблице Поставки (рисунок 3).
Рисунок 3



Результат работы ХП может быть также возвращен в виде кода ошибки. В языке T-SQL код ошибки задается с помощью оператора RETURN, завершающего выполнение ХП, например:
...
// Завершить процедуру, вернув код ошибки 7
RETURN 7
...



Или
...
// Завершить процедуру, вернув код ошибки из переменной @err
RETURN @err
...



В клиентском приложении код ошибки доступен в компоненте TADOStoredProc в виде параметра с именем @RETURN_VALUE. В следующем примере вызывается некоторая ХП, код ошибки которой считывается в поле EditError:
...
// Выполнить процедуру
ADOStoredProc4.ExecProc;
// Считать значение кода ошибки
EditError.Text :=
ADOStoredProc4.Parameters.ParamValues['@RETURN_VALUE'];
...



Таким образом, код ошибки можно рассматривать как особый вид выходного параметра. В массиве Parameters коду ошибки всегда соответствует элемент с индексом 0.

Опубликовал Kest March 25 2009 20:06:29 · 5 Комментариев · 65535 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
RETURN October 31 2009 20:53:07
Скажите пожалуйста, куда писать, при вызове процедуры с выходными параметрами?

DECLARE @TotalCount INT
EXEC sp3 @TotalCount OUTPUT
Kest November 01 2009 15:22:28
Это язык tsql
declare - объявление
exec - вызов
в Microsoft SQL Server можно выполнить этот код
N-Drew November 02 2009 23:25:47
Подскажите пожалуйста, вот такая конструкция :
ADOStoredProc1.ExecProc;
ADOTable1.Refresh;
у меня не работает (то бишь не обновляет данные в гриде) если в процедуру я передаю входные данные. То есть пример описанный в параграфе "Особенности передачи параметров" - у меня не отрабатывает должным образом. данные в базу добавляются но в гриде не отображаются. Причем самый первый пример там где нет никаких параметров - отрабатывает и обновляет данные в гриде - нормально.
Использую Delphi2009 и MSSQL 2005 (ADO коннект через Native Client).
Kest November 02 2009 23:43:12
да, вроде в дельфе была такая проблемка , нужно было вместо refresh писать: adoconnection1.Connected:= false, затем true или что то типо этого точно не помню, поэкспериментируй smiley
N-Drew November 03 2009 12:13:31
Проблему решил вот такой конструкцией
ADOTable1.Active := false;
ADOTable1.Active := true;
P.S. Как выяснилось что конструкция ADOTable1.Refresh НЕ должна работать с хранимками в которых идет Insert... (как описано в параграфе "Особенности передачи параметров" ) потому как Метод ADO Resync не перезапускает набор данных и оттого не отображает новые данные.
http://www.w3schools.com/ado/met_rs_resync.asp
А отображает изменения в уже существующих. Оттого первый пример работает.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере!
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Мониторинг сервер...
Ранги для форума
Image Browser [Ис...
JanComp
iComm v.6.1 - выв...
Советы от Даниилы...
Самоучитель Прогр...
Песочные часы
Error mod
Библия хакера 2 К...
Win-Prolog 3.618
Delphi Russian Kn...
3D Тетрис [Исходн...
Реализация ЭЦП по...
Добавление к ссы...
Синтаксический ан...
Dreamsoft Progres...
Усложнённый кальк...
С. Г. Горнаков - ...
Scrrlcaptoin

Топ загрузок
Приложение Клие... 100269
Delphi 7 Enterp... 75065
Converter AMR<-... 20016
Borland C++Buil... 10470
GPSS World Stud... 8817
Borland Delphi ... 7469
Turbo Pascal fo... 6867
Visual Studio 2... 4868
Калькулятор [Ис... 3836
FreeSMS v1.3.1 3481
Случайные статьи
Бесплатный «межгород»
Функция GetGraphMo...
Основные объекты W...
Физическая природ...
Ограничение возмож...
подпись ко всем по...
Менеджмент
Реализация требова...
Почему многих надо...
Глава 13
установки)300 клие...
Как получить домен...
Работа с изображением
Как донести до кли...
Легенда
Основные функции ш...
Функция list1
Тема адресации и с...
Карта CLEAR
Режим с обострением
tldЧтобы регистрир...
Табл. 15-6.
Структура наследов...
Синтаксис - Микро ...
Настройка объектов
Статистика



Друзья сайта
Программы, игры


  • Ugg australia
  • Модная одежда и обувь UGG с доставкой по РФ
  • ugghouse.ru
Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?