Во второй версии
Firebird появилось несколько нововведений. Одно из них это инструкция
EXECUTE BLOCK.
Она позволяет выполнить блок инструкций на стороне сервера, фактически это виртуальная хранимая процедура.
Следующий пример демонстрирует использование ресурсов сервера базы данных для выполнения простого арифметического действия:
publicvoid ExecuteBlockSQLTest()
{
// Описание: EXECUTE BLOCK - выполнение команд на стороне сервера Firebird 2.0. и выше
OleDbConnection con = OpenFB2Connection();
OleDbTransaction trans = con.BeginTransaction();
//текст командыstring execute_block_data =
"EXECUTE BLOCK (X INTEGER = :X) \n" +
"RETURNS (Y INTEGER) \n" +
"AS \n" +
"BEGIN \n" +
" Y = X * 2; \n" +
"SUSPEND; \n" +
"END \n";
//входящий параметрint in_parameter_X = 2;
OleDbCommand cmd = new OleDbCommand(execute_block_data, con, trans);
cmd.Parameters.AddWithValue("X", in_parameter_X);
//выполнение команды EXECUTE BLOCK
Assert.AreEqual((int)cmd.ExecuteScalar(), in_parameter_X * 2);
trans.Commit();
con.Close();
}
Еще одно новшество, благодаря которому работа с Firebird 2.0.
стала проще - это инструкция INSERT RETURNING.
Фактически эта команда позволяет выполнить операцию вставки данных и прочитать значения,
которые были добавлены в процессе этой операции.
Это актуально для получения значения идентификатора новой записи, для которого использовался генератор:
publicvoid InsertReturning()
{
// Описание: INSERT RETURNING - получение вставленных значений, подключение к Firebird 2.0 и выше
OleDbConnection con = OpenFB2Connection();
OleDbTransaction trans = con.BeginTransaction();
//новая команда INSERT RETURNING
OleDbCommand cmd = new OleDbCommand(
"insert into customer (cust_no, customer) \n" +
"values(GEN_ID(CUST_NO_GEN,1),:customer_name) \n" +
"RETURNING cust_no",con,trans);
cmd.Parameters.AddWithValue("customer_name", "New customer");
//добавляем один выходной параметр
cmd.Parameters.Add("customer_no", OleDbType.Integer)
.Direction =ParameterDirection.Output;
Assert.AreEqual(1, cmd.ExecuteNonQuery());
//удаляем запись, используя значение генератора, полученного //через INSERT .. RETURNING
OleDbCommand cmd_delete = new OleDbCommand(
"delete from customer where cust_no=?", con, trans);
cmd_delete.Parameters.AddWithValue("?",cmd.Parameters["customer_no"].Value);
Assert.AreEqual(1, cmd_delete.ExecuteNonQuery());
trans.Commit();
con.Close();
}
СПРАВКА
В версии Firebird 2.0 отсутствует возможность возвращать результаты для операций отличных от операции вставки.
Данная возможность появилась позже в версии Firebird 2.1.
Помимо стандартных операций UPDATE, DELETE, добавилась еще одна новая инструкция UPDATE OR INSERT RETURNING.
Инструкция ROLLBACK RETAIN
ROLLBACK RETAIN - позволяет откатить транзакцию на момент старта или до последнего вызова
COMMIT_RETAIN, оставляя возможность её дальнейшего использования. Давайте рассмотрим это на примере:
publicvoid RollbackRetainTest()
{
// Описание: ROLLBACK RETAIN - получение вставленных значений, подключение к Firebird 2.0 и выше
OleDbConnection con = OpenFB2Connection();
OleDbTransaction trans = con.BeginTransaction();
//insert new record
OleDbCommand cmd = new OleDbCommand(
"insert into customer (cust_no, customer) " +
"values(GEN_ID(CUST_NO_GEN,1),'New customer')", con, trans);
Assert.AreEqual(1, cmd.ExecuteNonQuery());
//ROLLBACK RETAIN new OleDbCommand("ROLLBACK RETAIN", con, trans).ExecuteNonQuery();
// транзакция остается активной и мы можем выполнять команды снова
cmd = new OleDbCommand(
"select count(*) from customer", con, trans);
Assert.IsTrue((int)cmd.ExecuteScalar() > 0 );
trans.Commit();
con.Close();
}
Инструкция ROWS
Ключевое слово ROWS соответствует последним стандартам ANSI SQL и является альтернативой FIRST/SKIP.
Оно позволяет указать количество обрабатываемых записей. Может быть использовано в UNION, любых подзапросах,
а так же в командах DELETE и UPDATE. Следующий пример читает из базы данных записи с первой по третью:
publicvoid RowsKeywordTest()
{
// Описание: ROWS - альтернатива FIRST/SKIP, доступно в Firebird 2.0 и выше
OleDbConnection con = OpenFB2Connection();
OleDbTransaction trans = con.BeginTransaction();
//command will return 3 records
OleDbCommand cmd = new OleDbCommand(
"select * from customer rows 1 to 3", con, trans);
short rec_count = 0;
using (OleDbDataReader reader = cmd.ExecuteReader())
while (reader.Read()) { rec_count++; }
Assert.AreEqual(3, rec_count);
trans.Commit();
con.Close();
}
Производные таблицы (Derived Tables)
Производные таблицы (Derived tables) - это именованные наборы, основанные на выборке SELECT.
В следующем примере на основе таблицы EMPLOYEE формируется производная таблица EMPLOYEE_DERIVED_TABLE с новыми полями:
select * from
(select EMP_NO, FIRST_NAME || ' ' || LAST_NAME from employee)
as EMPLOYEE_DERIVED_TABLE (ID, FULL_NAME)
Прочие изменения
В статье приведены примеры только некоторых изменений в DML Firebird 2.0. Среди прочих можно выделить:
Именованные курсоры (Named cursors) для PSQL
Новые функции и операторы DML и DDL (IIF, CREATE SEQUENCE, NEXT VALUE FOR, и т.д.)
Поддержка планов для операций обновления и удаления.
Улучшенный UNION, CROSS JOIN.
За дополнительной информацией советуем обратиться к документу