Специальная поддержка DML (Data Manipulation Language)
Во второй версии Firebird появилось несколько нововведений. Одно из них это инструкция EXECUTE BLOCK. Она позволяет выполнить блок инструкций на стороне сервера, фактически это виртуальная хранимая процедура. Следующий пример демонстрирует использование ресурсов сервера базы данных для выполнения простого арифметического действия:
public void ExecuteBlockSQLTest() { 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(); }
Еще одно новшество, которое подарил нам FB2, это инструкция INSERT RETURNING. Фактически она позволяет выполнить операцию вставки данных и прочитать значения, которые были добавлены в процессе этой операции. Это особенно актуально для получения значения идентификатора новой записи, для которого использовался генератор:
public void InsertReturning() { 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(); }
ROLLBACK RETAIN – позволяет откатить транзакцию на момент старта или до последнего вызова COMMIT_RETAIN, оставляя возможность её дальнейшего использования. Давайте рассмотрим это на примере:
public void RollbackRetainTest() { 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();
//transaction will be active and we can execute some command again
cmd = new OleDbCommand( "select count(*) from customer", con, trans);
Assert.IsTrue((int)cmd.ExecuteScalar() > 0 );
trans.Commit(); con.Close(); }
Ключевое слово ROWS соответствует последним стандартам ANSI SQL и является альтернативой FIRST/SKIP. Оно позволяет указать количество обрабатываемых записей. Может быть использовано в UNION, любых подзапросах, а так же в командах DELETE и UPDATE. Следующий пример читает из базы данных записи с первой по третью:
public void RowsKeywordTest() { 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(); }
Я привел примеры только некоторых изменений в DML Firebird 2, которые требовали специальной поддержки со стороны Ole Db провайдера.Для изучения полного списка изменений рекомендую вам обратиться к документу: Firebird 2 release notes. Там действительно есть много того, что может заинтересовать разработчиков. Это производные таблицы, новые функции, улучшенный UNION, инструкция NEXT VALUE FOR, поддержка планов для операций обновления и удаления и много чего другого.