Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Копия2 отчет 2.doc
Скачиваний:
2
Добавлен:
11.11.2019
Размер:
905.22 Кб
Скачать

Вызов хранимых процедур

Существуют два способа обработки результатов хранимых процедур:

  • хранимая процедура возвращает результирующее множество

  • результат выполнения хранимой процедуры помещается в OUT параметры команды

Для первого способа используется обычная SQL-инструкция:

select * from stored_procedure_name(…)

Результат её выполнения обрабатывается при помощи объекта OleDbDataReader:

public void StoredProcedureResultSetTest()

{

OleDbConnection con = ConnectionProvider.CreateConnection();

con.Open();

OleDbTransaction trans = con.BeginTransaction();

//select stored procedure in params

OleDbCommand cmd_in_params =

new OleDbCommand("select cust_no from CUSTOMER", con, trans);

//select mail label through the stored procedure

OleDbCommand cmd_stored_proc =

new OleDbCommand("select * from mail_label(:cust_no)", con, trans);

//add one IN parameter

cmd_stored_proc.Parameters.Add("cust_no", OleDbType.Integer);

//execure reader

using (OleDbDataReader rdr = cmd_in_params.ExecuteReader(CommandBehavior.CloseConnection))

{

//for each customer No

while (rdr.Read())

{

cmd_stored_proc.Parameters["cust_no"].Value = rdr["cust_no"];

using (OleDbDataReader rdr_out = cmd_stored_proc.ExecuteReader())

{

Console.WriteLine("Customer №" + rdr["cust_no"]);

while (rdr_out.Read())

for (int i = 0; i < rdr_out.FieldCount; i++)

Console.WriteLine(rdr_out.GetName(i) + "=" + rdr_out[i]);

Console.WriteLine();

}

}

}

}

Второй способ – вызов хранимой процедуры через инструкцию:

execute procedure stored_procedure_name

Триггеры - одно из замечательнейших изобретений разработчиков баз данных. Триггеры позволяют придать "активность" данным, хранящимся в базе данных, централизовать их обработку и упростить логику клиентских приложений. Что же такое триггер? Триггер в InterBase - это особый вид хранимой процедуры, которая выполняется автоматически при вставке, удалении или модификации записи таблицы или представления (view). Триггеры могут "срабатывать" непосредственно до или сразу же после указанного события. Может быть, это звучит достаточно сложно, однако, как это бывает во многих случаях, сама идея, лежащая в основе триггеров, очень проста. Как вы знаете. SQL дает возможность нам вставлять, удалять и модифицировать данные в таблицах базы данных при помощи соответствующих команд - INSERT, DELETE и UPDATE. Согласитесь, что было бы неплохо иметь возможность перехватить передаваемую команду и что-нибудь сделать с данными, которые добавляются, удаляются или изменяются. Например, записать эти данные в специальную табличку, а заодно записать, кто и когда произвел операцию над данной таблицей. Или сразу же проверить вставляемые данные на какое- нибудь хитрое условие, которое невозможно реализовать с помощью опции CHECK (см. выше главу "Ограничения базы данных"), и в зависимости от результатов проверки принять проводимые изменения или отвергнуть их; изменить эти данные на основании какого-либо запроса или изменить данные в других связанных таблицах. Вот для того, чтобы выполнять какие-либо действия, связанные с изменением данных в базе данных, и существуют триггеры. Фактически триггер представляет собой набор команд процедурного языка InterBase, который исполняется при выполнении операций TNSERT/DELETE/UPDATE В отличие от хранимых процедур, триггер никогда ничего не возвращает (да и некому возвращать. ведь триггер явно не вызывается) По той же причине он не имеет также входных параметров, но вместо них имеет контекстные переменные NEW и OLD. Эти переменные позволяют получить доступ к полям таблицы, к которой присоединен триггер (мы расскажем об этом чуть позже). Триггеру предназначена роль виртуального цензора, который просматривает "письма" и который волен сделать все, что угодно, - пропустить их неизменными, подправить их, просигнализировать об ошибках или даже "доложить об этом" кому следует. Триггер всегда привязан к какой-то определенной таблице или представлению и может "перехватывать" данные только этой таблицы. Давайте рассмотрим классификацию триггеров и назначение каждого вида. Как уже было сказано, существует 3 основных SQL-операции, применимые к данным, - INSERT/DELETE/UPDATE. Соответственно первое разделение триггеров - по обслуживаемым операциям. Каждый конкретный триггер привязан к какой-либо операции, т. е. триггер срабатывает, когда в "его" таблице происходит данная операция.

В клоне Yaffil 1 0 реализована поддержка универсальных триггеров, срабатывающих при любой операции.

Также срабатывание триггера может происходить "до" и "после" операции. Таким образом, мы получаем 6 возможных видов триггеров на таблицу - до и после каждой из трех возможных SQL-операций.

Пример триггера

Давайте рассмотрим простой пример триггера, который срабатывает ДО ВСТАВКИ в таблицу и заполняет поле первичного ключа. Мы воспользуемся в качестве основы для триггера таблицей из примера в главе "Таблицы. Первичные ключи и генераторы" этой части: CREATE TABLE Table_example (  ID INTEGER NOT NULL,  NAME VARCHAR(80),  PRICE_1 DOUBLE PRECISION,  CONSTRAINT pkTable PRIMARY KEY (ID)); Здесь поле ID является первичным ключом и значения этого поля должны быть уникальными в пределах таблицы. Чтобы обеспечить выполнение этого требования, создадим генератор и триггер, который будет получать значение генератора и подставлять его в таблицу. Таким образом, в поле ID всегда будет уникальные значения, так как значение генератора будет увеличиваться каждый раз при обращении к триггеру. Итак, создаем генератор:  CREATE GENERATOR GEN_TABLE_EXAMPLE_ID; И устанавливаем его начальное значение в единицу: SET GENERATOR GEN_TABLE_EXAMPLE_ID TO 1; Теперь необходимо создать триггер. Надо сказать, что триггер, как и хранимая процедура, может содержать в своем теле несколько операторов, разделенных точкой с запятой. Поэтому если вы не используете один из инструментов, рекомендованных в приложении "Инструменты администратора и разработчика InterBase", а работаете с isql, то вам необходимо воспользоваться командой смены разделителя команд SET TERM, как это было описано в главе "Хранимые процедуры". Мы же будем приводить тексты триггеров без обрамления командами смены разделителя. Итак, рассмотрим текст нашего триггера: CREATE TRIGGER Table_example_bi FOR Table_example  ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW. ID GEN_ID(GEN_TABLE_EXAMPLE_ID, 1); END Как видите, триггер очень напоминает хранимую процедуру (фактически, как )же было сказано, это и есть особая разновидность ХП), но есть и несколько отличий Давайте подробно разберем "строение" триггера. Описание команды создания триггера начинается с ключевых слов CREATE TRIGGER, после которых следует имя триггера - Table_example_bi. Потом следует ключевое слово FOR, после которого указано имя таблицы, для которой создается триггер, - Table_example. На второй строке команды приводится описание сущности триггера - ключевое слово ACTIVE указывает, что триггер является "активным". Триггер также может быть переведен в состояние INACTIVE. Это означает, что он будет храниться в базе данных, но он не будет срабатывать. Сочетание ключевых слов BEFORE INSERT определяет, что триггер срабатывает ДО ВСТАВКИ; а ключевое слово POSITION и число 0 указывают очередность (позицию) создаваемого триггера среди триггеров того же типа для данной таблицы. Позиция триггера нужна потому, что в InterBase возможно создать более 32000 триггеров каждого вида (например, BEFORE INSERT или AFTER UPDATE), и серверу нужно указать, в каком порядке эти триггеры будут выполняться. Триггеры с меньшей позицией выполняются первыми. Если имеется несколько триггеров с одинаковой позицией, то они будут выполняться в алфавитном порядке. Все рассмотренное выше до ключевого слова AS образует заголовок триггера. После AS следует тело триггера. Собственно в теле и осуществляется вставка значения в поле первичного ключа. Но сначала с помощью уже знакомого вам оператора IF.. .THEN проверяется, не было ли заполнено это поле на клиенте. Выражение проверки возвращающей булеву TRUE (истина) или FALSE (ложь), выгядит так: NEW. ID IS NULL "Интересно, что такое NEW?" - спросите вы. Это одна из особенностей, присущая только триггерам, - контекстная переменная

4.12. Формирование и вывод отчётов

Одним из наиболее важных и трудоемких процессов в написании программ на VB является создание твердых копий документов. Существуют следующие способы создания отчетов:  1. Cоздание отчетов с помощью Crystal Reports.  2. Создание отчетов с использованием генератора отчетов приложения Access 97.  3. Создание отчетов с использованием непосредственной пересылки команд принтеру. 4. Создание отчетов с использованием объекта Printer языка Visual Basic. 

1.Crystal Reports.  Наиболее популярный способ, позволяющий довольно быстро создавать бланк отчета и в процессе выполнения программы выводить его на печать с заполнением данными из базы данных. Недостатки - бланк отчета формируется заранее. Если у Вас например, в процессе работы программы возникает необходимость выводить на печать сотни таблиц с изменяющимся количеством столбцов в зависимости от выбранных пользователем выборок из баз данных - это способ будет очень неудобен. Ко всему прочему на старых принтерах возникают проблемы с получением отчетов, точно воспроизводящих графическую часть - разделительные линии по отношению к тексту не всегда на своих местах. Способы использования Crystal Reports многократно описаны в литературе, поэтому мы не будем здесь подробно на них останавливаться. 

2.Генератор отчетов из Access 97.  Очень неплохой генератор отчетов, но при его использовании из VB5 для вывода отчета на печать необходимо иметь на машине Access, что далеко не всегда удобно и приемлемо. Вызов готового отчета из VB осуществляется довольно просто:  Private Sub cmdReport_Click()            Dim Report As New Access.Application            Report.OpenCurrentDatabase ("C:\...путь к базе данных...")            'Запуск в Access формы, запускающей отчет            Report.DoCmd.OpenForm "ReportDialog", acNormal            Report.Visible=True  

3.Непосредственная пересылка данных на принтер.  Применяется для вывода на принтер растровых графических изображений через порты LPT1, LPT2 с помощью кодов PSL (Printer Control Language - язык управления принтером, который можно использовать на HP Lazer Jet 2 и более поздних моделях). Изображения разбиваются на маленькие составные части и передаются на принтер как набор точек.  Кроме того существует способ непосредственной записи в порты LPT1,LPT2, контролируемыe операционной системой с помощью оператора Print #, аналогично записи в обычный текстовый файл. При использовании этих методов есть риск привязать программу к параметрам конкретного принтера. 

4.13. Запросы к базе данных

Типы запросов данных

Есть четыре основных типа запросов данных в SQL, которые относятся к так называемому языку манипулирования данными (Data Manipulation Language или DML):

  • SELECT – выбрать строки из таблиц;

  • INSERT – добавить строки в таблицу;

  • UPDATE – изменить строки в таблице;

  • DELETE – удалить строки в таблице;

Каждый из этих запросов имеет различные операторы и функции, которые используются для того, чтобы произвести какие-то действия с данными. Запрос SELECT имеет самое большое количество опций. Существуют также дополнительные типы запросов, используемых вместе с SELECT, типа JOIN и UNION. Но пока, мы сосредоточимся только на основных запросах.

Использование запроса SELECT для выборки нужных данных

Чтобы получить информацию, хранящуюся в базе данных используется запрос SELECT. Базовое действие этого запроса ограничено одной таблицей, хотя существуют конструкции, обеспечивающие выборку с нескольких таблиц одновременно. Для того, чтобы получить все строки данных для специфических столбцов, используется запрос такого вида:

SELECT column1, column2 FROM table_name;

Также, можно получить все столбцы из таблицы, используя подстановочный знак «*»:

SELECT * FROM table_name;

Это может быть полезно в том случае, когда вы собираетесь выбрать данные с определенным условием WHERE. Следующий запрос возвратит все столбцы со всех строк, где «column1» содержит значение «3»:

SELECT * FROM table_name WHERE column1=3;

Кроме «=» (равно), существуют следующие условные операторы:

Условные операторы

=

Равно

<>

Не равно

>

Больше

<

Меньше

>=

Больше или равно

<=

Меньше или равно

Дополнительно можно использовать условия BITWEEN и LIKE для сравнения с условием WHERE, а так же комбинации операторов AND и OR.

SELECT * FROM table_name WHERE ((Age >= 18) AND (LastName BETWEEN ‘Иванов’ AND ‘Сидоров’)) OR Company LIKE ‘%Motorola%’;

Что в переводе на русский язык означает: выбрать все столбцы из таблицы table_name, где значение столбца age больше или равно 18, а также значение столбца LastName находится в алфавитном промежутке от Иванов до Сидоров включительно, или же значением столбца Company является Motorola.

Использование запроса INSERT для вставки новых данных

Запрос INSERT используется для создания новой строки данных. Для обновления уже существующих данных или пустых полей строки нужно использовать запрос UPDATE.

Примерный синтаксис запроса INSERT:

INSERT INTO table_name (column1, column2, column3) VALUES (‘data1’, ‘data2’, ‘data3’);

Если вы собираетесь вставлять все значения в порядке, в котором находятся столбцы таблицы, то можно и не указывать имена столбцов, хотя для удобочитаемости это предпочтительнее. Кроме того, если вы перечисляете столбцы, необязательно указывать их по порядку нахождения в базе данных, пока значения, которые вы вводите, соответсвуют этому порядку. Вы не должны перечислять столбцы, в которые не вводится информация.

Изменяется уже существующая информация в базе данных очень похожим образом.

Запрос UPDATE и условие WHERE

UPDATE используется для того, чтобы изменить существующие значения или освободить поле в строке, поэтому новые значения должны соответствовать существующему типу данных и обеспечивать приемлемые значения. Если вы не хотите изменить значения во всех строках, то нужно использовать условие WHERE.

UPDATE table_name SET column1 = ‘data1’, column2 = ‘data2’ WHERE column3 = ‘data3’;

Вы можете использовать WHERE для любого столбца, включая тот, который хотите изменить. Это используется когда необходимо заменить одно определенное значение на другое.

UPDATE table_name SET FirstName = ‘Василий’ WHERE FirstName = ‘Василий’ AND LastName = ‘Пупкин’;

Будьте осторожны! Запрос DELETE удаляет целые строки

Запрос DELETE полность удаляет строку из базы данных. Если вы хотите удалить одно единственное поле, то нужно использовать запрос UPDATE и установить для этого поля значение, которое будет являться аналогом NULL в вашей программе. Будьте внимательны, и ограничивайте ваш запрос DELETE условием WHERE, иначе вы можете потерять все содержимое таблицы.

DELETE FROM table_name WHERE column1 = ‘data1’;

Как только строка была удалена из вашей базы данных, она не подлежит восстановлению, поэтому желательно иметь столбец по имени «IsActive», или что-то типа того, который вы можете изменить на ноль, что будет указывать на блокировку представления данных из этой строки.