Навигация
Главная
Поиск
Форум
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
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 9
На сайте нет зарегистрированных пользователей

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

База данных студентов на Delphi (файл записей) + Блок схемы
Игра Sokoban на Delphi + Блок схемы
Диплом RSA, ЭЦП, сертификаты, шифрование на C#

Вызов хранимых процедур из приложения с использованием технологии 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 17:06:29 · 8 Комментариев · 65535 Прочтений · Для печати

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


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

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

А вот так когда написал, переменные передались
ADOStoredProc1.ProcedureName:='Имя процедуры';
ADOStoredProc1.Parameters.Refresh;
ADOStoredProc1.Parameters.ParamByName('@переменная1'smiley.Value:=Edit1.Text;
ADOStoredProc1.Parameters.ParamByName('@переменная2'smiley.Value:=Edit2.Text;
ADOStoredProc1.Parameters.ParamByName('@переменная3'smiley.Value:=Edit3.Text;
ADOStoredProc1.ExecProc;
Василий November 12 2018 12:28:04
все бы хорошо ( и понятно) но я искал с ADOQuery пример.
т.е. когда я добавляю в 2 таблицы данные, где в 1-й таблице id=счетчик -авто. а вот 2-й int.
и есть связь один_ко_многим.
и вот когда я добавляю в бд запись, то нужно после добавления , из 1-й таблицы забрать id вставки (думаю использовать select @@identity ) но вот как это вернуть в параметр, а потом через делфи отобразить?... или как тут сделать - отдельной процедурой?..
а при вставке, сразу забрать результат не получится?
(спасибо)
Василий November 14 2018 14:52:19
мда.. вижу что тема умерла.... жаль..
Добавить комментарий
Имя:



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

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

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

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

Пароль



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

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

Случайные загрузки
Email
Разработка распре...
Язык программиров...
Text3D
Библия хакера 2 К...
Алгоритм DES шифр...
Delphi и технолог...
Работа с картотеками
AdBlaster v2.5 - ...
MiniTetris [Исход...
Карта сайта
Fig [Исходник на ...
Самоучитель PHP 4
Язык программиров...
Простой текстовый...
Zoom [Исходник на...
ZipTV
Шифрование по алг...
Программа предназ...
Введение в станда...

Топ загрузок
Приложение Клие... 100771
Delphi 7 Enterp... 97787
Converter AMR<-... 20259
GPSS World Stud... 17014
Borland C++Buil... 14186
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5968
Visual Studio 2... 5205
Microsoft SQL S... 3661
Случайные статьи
Форма контроля до...
Площадь треугольника
Используйте систем...
Моделирование расп...
Недвижимость в Чите
Оболочка независим...
Задача 3 посвящена...
Управление страницами
Где мы находимся?
Программирование: ...
Идеальная ЛВС
Манипуляторы
10 Заблуждений при...
Чтобы исключить уг...
Рекурсия
26 шагов к 15 тыс....
События - блокирую...
Функция MessageBox...
При проигрывании DVD
Имитация файлов и ...
Механизмы динамиче...
Форматы таблиц
• Убедитесь, что е...
Таблица хэшировани...
Шинная архитектура
Статистика



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


  • купить настоящий аттестат в Самаре тут
  • samara.simidiplom.com
Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?