Исполнение запросов в БД

Материал из Oktell
Перейти к: навигация, поиск
Наверх Запуск служебных сценариев<<< Исполнение запросов в БД >>>Вспомогательные методы

Исполнение запросов в БД

  • string ExecDbQuery ( string xml ). Осуществляет запрос к БД средствами сервера Oktell. Метод принимает на вход сложный параметр. Выполняет перечисленные в параметре операции и возвращает в аналогичной структуре результаты выполнения. В простейшем случае параметр указывает единственную операцию. В общем виде последовательно выполняться может неограниченное число перечисленных операций, описываемых ниже в данном разделе.

Структура параметра-запроса:

<?xml version="1.0" encoding="utf-16"?>
 <oktellcommapper version="80710">
 <data name="dboperation" count="...">
   <property_set name="..." id="...">
     ...
   </property_set>
 ...........................................
 ...........................................
 ...........................................
   <property_set name="..." id="...">
     ...
   </property_set> 
 </data>
 </oktellcommapper>


Каждый вложенный блок property_set указывает на отдельную операцию. В простейшем случае соответственно этот блок присутствует в единственном экземпляре и весь параметр принимает вид:

<?xml version="1.0" encoding="utf-16"?>
 <oktellcommapper version="80710">
 <data name="dboperation" count="1">
   <property_set name="..." id="...">
     ...
   </property_set>
 </data>
 </oktellcommapper>


Код идентификатора операции может не указываться. Он используется лишь для сопоставления операции в запросе и ответе во внешнем ПО.

Возвращаемое значение имеет вид, аналогичный параметру запроса. Каждая операция имеет свое представление в виде блока property_set, расположенного в том же месте, где и в запросе.

Структура ответа:

<?xml version="1.0" encoding="utf-16"?>
 <oktellxmlmapper version="80710">
 <data name="execdbquery" count="...">
   <property_set name="..." id="...">
     <property_simple key="resultcode" value="..." name="..." />
     <property_cdata key="resultdescription"><![CDATA[...]]></property_cdata>
        ...
   </property_set>
 ...........................................
 ...........................................
 ...........................................
   <property_set name="..." id="...">
     <property_simple key="resultcode" value="..." name="..." />
     <property_cdata key="resultdescription"><![CDATA[...]]></property_cdata>
     ...
   </property_set> 
 </data>
 </oktellxmlmapper>

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


Поддерживаемые варианты взаимодействия с БД

  • db. Осуществляет запрос к БД средствами Oktell.

В теле элемента property_set должно быть указано свойство sqltext. Текст запроса должен иметь полностью сформированный вид и будет передан без дополнительных параметров на сервер, а затем в БД. Запрос должен представлять из себя один batch-блок, и может иметь любую сложность (содержать переменные, курсоры, вести обработку в цикле и т.д.). При необходимости текст запроса может быть преобразован в Base64 (предварительное преобразование в Unicode) и передан через поле sqltextb64. Присутствие одного из них обязательно.

Возвращаемое значение (одиночный набор) будет преобразовано в XML-структуру и возвращено в plugin-программу в виде ответа (в соответствующем разделе полного запроса).

При корректном парсинге параметров и отправке запроса на сервер в любом случае в свойство resultcode будет занесен успешный результат. Однако свойство sqlresultcode будет содержать код результата исполнения запроса в БД, который может отличаться от успешного.

Структура запроса:

<property_set name="db" id="...">
   <property_cdata key="sqltext"><![CDATA[...]]></property_cdata>
 </property_set>


Структура ответа в случае успешного выполнения:

<property_set name="db" id="...">
 <!--##### Общие свойства #####-->
 	<property_simple key="resultcode" value="100" name="Success" />
 	<property_cdata key="resultdescription"><![CDATA[Success]]></property_cdata>
 	<property_simple key="sqlresultcode" value="0" name="qrSuccess" />
 	<property_cdata key="sqlresultdescription"><![CDATA[qrSuccess]]></property_cdata>
 	<!--##### Возвращаемый набор #####-->
 	<property_collection name="table" count="...">
 	<!--##### Описание столбцов #####-->
 		<property_set name="tableheader">
 			<property_collection name="columns" count="...">
 			<!--##### Один столбец: индекс, название, тип и полное название типа #####-->
 			<property_set name="columninfo" id="0">
 				<property_simple key="index" value="0" />
 				<property_simple key="name" value="Id" />
 				<property_simple key="typename" value="Guid" />
 				<property_cdata key="typefullname"><![CDATA[System.Guid]]></property_cdata>
 			</property_set>
 			<property_set name="columninfo" id="2">
 				<property_simple key="index" value="1" />
 				<property_simple key="name" value="Name" />
 				<property_simple key="typename" value="String" />
 				<property_cdata key="typefullname"><![CDATA[System.String]]></property_cdata>
 			</property_set>
 			...............
 			</property_collection>
 		</property_set>
 		<!--##### Раздел с данными #####-->
 		<property_set name="tabledata">
 			<property_collection name="rows" count="2">
 			<!--##### Одна строка: индекс строки, коллекция ячеек (значений) #####-->
 				<property_set name="row" id="0">
 				<!--##### Все ячейки #####-->
 					<property_collection name="cells" count="2">
 					<!--##### Одна ячейка: индекс столбца, значение #####-->
 						<property_set name="cell" id="0">
 						<property_simple key="cellvalue" value="17e640e1-1d55-4e45-a193-0469cbcd2dce" />
 						</property_set>
 						<property_set name="cell" id="1">
 						<property_cdata key="cellvalue"><![CDATA[Максим]]></property_cdata>
 						</property_set>
 					</property_collection>
 				</property_set>
 				<property_set name="row" id="1">
 					<property_collection name="cells" count="2">
 						<property_set name="cell" id="0">
 						<property_simple key="cellvalue" value="309a147f-6248-4fbd-8b28-09b679c8297a" />
 						</property_set>
 						<property_set name="cell" id="1">
 						<property_simple key="cellvalue" value="z08" />
 						</property_set>
 					</property_collection>
 				</property_set>
 			</property_collection>
 		</property_set>
 	</property_collection>
 </property_set>


  • dbdataset. Осуществляет запрос к БД средствами Oktell. В отличие от метода «db» структуру, получаемую на сервере, загружает в DataSet и формирует на ее базе стандартную XML строку, преобразованную в Base64.

Для обратного преобразования необходимо полученную из поля CDATA строку подвергнуть обработке следующим кодом (C#):

DataSet ds = new DataSet();
MemoryStream ms = new MemoryStream ( Convert.FromBase64String ( dsxml ) );
ds.ReadXml ( ms );

В поле sqltext передается текст запроса SQL. Текст запроса должен иметь полностью сформированный вид и будет передан без дополнительных параметров на сервер, а затем в БД. Запрос должен представлять из себя один batch-блок, и может иметь любую сложность (содержать переменные, курсоры, вести обработку в цикле и т.д.). При необходимости текст запроса может быть преобразован в Base64 (предварительное преобразование в Unicode) и передан через поле sqltextb64. Присутствие одного из них обязательно.

Структура запроса:

<property_set name="dbdataset" id="...">
 <property_cdata key="sqltext"><![CDATA[...]]></property_cdata>
 </property_set>


Структура ответа в случае успешного выполнения:

<property_set name="db" id="...">
 <!--##### Общие свойства #####-->
 <property_simple key="resultcode" value="100" name="Success" />
 <property_cdata key="resultdescription"><![CDATA[Success]]></property_cdata>
 <property_simple key="sqlresultcode" value="0" name="qrSuccess" />
 <property_cdata key="sqlresultdescription"><![CDATA[qrSuccess]]></property_cdata>
 <!--##### Возвращаемый набор #####-->
 <property_collection name="dataset" count="1">
 <!--##### Описание столбцов #####-->
 <property_set name="datasetxmlb64">
 <property_cdata key="xmlb64"><![CDATA[.....Base64......]]></property_cdata>
 </property_set>
 </property_collection>
 </property_set>


  • dbarbitrarydataset. Осуществляет запрос к БД средствами Oktell. В отличие от методов «db» и «dbdataset» позволяет подключаться к различным БД посредством ADO, OLE, ODBC, Oracle. Cтруктуру, получаемую на сервере, загружает в DataSet и формирует на ее базе XML строку, преобразованную в Base64.

Для обратного преобразования необходимо полученную из поля CDATA строку подвергнуть обработке следующим кодом (C#):

DataSet ds = new DataSet();
MemoryStream ms = new MemoryStream ( Convert.FromBase64String ( dsxml ) );
ds.ReadXml ( ms );

Передаваемый параметр должен содержать указание направления (поле direction) числовым значением из следующего набора:

SQLServerSelf         = 1 //Подключение к БД Oktell
SQLServerOther        = 2 //Подключение к сторонней базе MS SQL
OLE                   = 3 //Подключение к OLE-драйверу
Oracle                = 4 //Подключение к Oracle-драйверу
Odbc                  = 5 //Подключение к ODBC драйверу


Если требуется подключение к собственной БД Oktell, поле direction можно не указывать.

Для подключения к сторонним БД необходимо указание строки подключения к БД (поле connectionstring). Если осуществляется подключение к собственной БД Oktell, строка подключения игнорируется.

В поле sqltext передается текст запроса SQL. Текст запроса должен иметь полностью сформированный вид и будет передан без дополнительных параметров на сервер, а затем в БД. Запрос должен представлять из себя один batch-блок, и может иметь любую сложность (содержать переменные, курсоры, вести обработку в цикле и т.д.). При необходимости текст запроса может быть преобразован в Base64 (предварительное преобразование в Unicode) и передан через поле sqltextb64. Присутствие одного из них обязательно.

Структура запроса:

<property_set name="dbarbitrarydataset" id="...">
 <property_cdata key="direction" value="3"/>
 <property_cdata key="connectionstring"><![CDATA[Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Base; Extended Properties=dBase IV]]></property_cdata>
 <property_cdata key="sqltext"><![CDATA[...]]></property_cdata>
 <property_cdata key="sqltextb64"><![CDATA[...]]></property_cdata>
 </property_set>


Если при выполнении запроса возникает ошибка или исключение, то конкретный код исключения возвращается в поле sqlresultcode, а коллекция dataset отсутствует. В случае успешного выполнения код возврата равен 0.

Структура ответа в случае успешного выполнения:

<property_set name="dbarbitrarydataset" id="...">
 <!--##### Общие свойства #####-->
 <property_simple key="resultcode" value="100" name="Success" />
 <property_cdata key="resultdescription"><![CDATA[Success]]></property_cdata>
 <property_simple key="sqlresultcode" value="0" />
 <!--##### Возвращаемый набор #####-->
 <property_collection name="dataset" count="1">
 <!--##### Описание столбцов #####-->
 <property_set name="datasetxmlb64">
  <property_cdata key="xmlb64"><![CDATA[.....Base64......]]></property_cdata>
 </property_set>
 </property_collection>
 </property_set> 


  • dbtransaction. Осуществляет запрос к БД средствами Oktell. Работает в транзакции. Работа с помощью метода состоит из нескольких этапов: создание подключения и транзакции, поочередное выполнение одного или нескольких запросов с возвратом результата выполнения в виде DataSet, и применении или откате транзакции. Поле mode параметра определяет режим работы (этап):
Сreate        = 1 //Подключение к БД, создание транзакции
Query         = 2 //Выполнение запроса в существующей транзакции
Commit        = 3 //Подтверждение и применение изменений
Rollback      = 4 //Откат транзакции к прежнему состоянию

Режим Create осуществляет подключение к БД и создает транзакцию. Подключение и транзакция сохраняются на сервере до момента выполнения метода OnQuery.dbtransaction в режиме Commit или Rollback. Транзакция автоматически откатывается и подключение закрывается в случае выхода пользователя из системы, но этого режима лучше избегать, так как активная транзакция может парализовать работу других служб. Передаваемый параметр должен содержать указание направления (поле direction) числовым значением из следующего набора:

 SQLServerSelf     = 1 //Подключение к БД Oktell
 SQLServerOther    = 2 //Подключение к сторонней базе MS SQL
 OLE               = 3 //Подключение к OLE-драйверу
 Oracle            = 4 //Подключение к Oracle-драйверу
 Odbc              = 5 //Подключение к ODBC драйверу


Если требуется подключение к собственной БД Oktell, поле direction можно не указывать. Для подключения к сторонним БД необходимо указание строки подключения к БД (поле connectionstring). Если осуществляется подключение к собственной БД Oktell, строка подключения игнорируется. Необходимо также определить поле checkcode, являющееся произвольным числовым значением, которое будет гарантировать доступ к транзакции только исполнителю. На каждом последующем режиме работы с транзакцией требуется указание того checkcode, который был определен при создании подключения. В противном случае метод не будет выполнен и будет возвращен код соответствующей ошибки (50045). Для создания новой транзакции необходимо сначала дождаться окончания выполнения предыдущей, или закрыть ее принудительно (методами Commit или Rollback с совпадающим кодом checkcode). Если в момент создания уже существует активная транзакция, будет возвращен код ошибки 50047.


Режим Query осуществляет запрос через ранее созданное подключение и активную транзакцию. Cтруктуру, получаемую на сервере, загружает в DataSet и формирует на ее базе XML строку, преобразованную в Base64. Для обратного преобразования необходимо полученную из поля CDATA строку подвергнуть обработке следующим кодом (C#):

DataSet ds = new DataSet();
MemoryStream ms = new MemoryStream ( Convert.FromBase64String ( dsxml ) );
ds.ReadXml ( ms );

В поле sqltext передается текст запроса SQL. Текст запроса должен иметь полностью сформированный вид и будет передан без дополнительных параметров на сервер, а затем в БД. Запрос должен представлять из себя один batch-блок, и может иметь любую сложность (содержать переменные, курсоры, вести обработку в цикле и т.д.). При необходимости текст запроса может быть преобразован в Base64 (предварительное преобразование в Unicode) и передан через поле sqltextb64. Присутствие одного из них обязательно. Также для выполнения запроса в транзакции требуется обязательное указание поля checkcode, которое должно соответствовать значению, определенному при создании подключения и транзакции. В противном случае будет возвращаться код соответствующей ошибки (50045 в случае, если код не совпадает, 50046 в случае, если транзакция не существует).


Режим Commit завершает транзакцию с применением изменений, а также закрывает подключение. После выполнения метода следующее обращение должно вновь создать подключение (возможно к другой БД). Для корректного выполнения метода требуется обязательное указание поля checkcode, значение которого должно соответствовать значению, определенному при создании подключения и транзакции. В противном случае метод не будет выполнен и будет возвращен код соответствующей ошибки.


Режим Rollback завершает транзакцию с откатом изменений, а также закрывает подключение. После выполнения метода следующее обращение должно вновь создать подключение (возможно к другой БД). Для корректного выполнения метода требуется обязательное указание поля checkcode, значение которого должно соответствовать значению, определенному при создании подключения и транзакции. В противном случае метод не будет выполнен и будет возвращен код соответствующей ошибки.

Возможные коды ошибок:

  • 50043 - Ошибка выполнения запроса
  • 50044 - Ошибка при подключении к указанной БД
  • 50045 - Переданный код транзакции не соответствует реальному
  • 50046 - Не обнаружена активная транзакция
  • 50047 - Транзакция уже существует
  • Прочие коды совпадают с кодами ошибок соответствующих драйверов подключения.


Примеры запросов

  • Создание транзакции:
<property_set name="dbtransaction" id="...">
 <property_cdata key="mode" value="1"/>
 <property_cdata key="direction" value="3"/>
 <property_cdata key="connectionstring"><![CDATA[Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Base; Extended Properties=dBase IV]]>
 </property_cdata>
 <property_cdata key="checkcode" value="42556232"/>
 </property_set>


  • Выполнение запроса:
<property_set name="dbtransaction" id="...">
 <property_cdata key="mode" value="2"/>
 <property_cdata key="checkcode" value="42556232"/>
 <property_cdata key="sqltext"><![CDATA[...]]></property_cdata>
 <property_cdata key="sqltextb64"><![CDATA[...]]></property_cdata>
 </property_set>


  • Применение (откат) транзакции:
<property_set name="dbtransaction" id="...">
 <property_cdata key="mode" value="3"/>
 <property_cdata key="checkcode" value="42556232"/>
 </property_set>

Если при выполнении запроса возникает ошибка или исключение, то конкретный код исключения возвращается в поле sqlresultcode, а коллекция dataset отсутствует. В случае успешного выполнения код возврата равен 0.


  • Структура ответа в случае успешного выполнения:
<property_set name="dbtransaction" id="...">
 <!--##### Общие свойства #####-->
 <property_simple key="resultcode" value="100" name="Success" />
 <property_cdata key="resultdescription"><![CDATA[Success]]></property_cdata>
 <property_simple key="sqlresultcode" value="0" />
 <!--##### Возвращаемый набор #####-->
 <property_collection name="dataset" count="1">
 <!--##### Описание столбцов #####-->
 <property_set name="datasetxmlb64">
  <property_cdata key="xmlb64"><![CDATA[.....Base64......]]></property_cdata>
 </property_set>
 </property_collection>
 </property_set>
Наверх Запуск служебных сценариев<<< Исполнение запросов в БД >>>Вспомогательные методы