C# - Oracle - нотатки на полях, Різне, Графіка, статті на
Колись давно, дуже давно.
Компанія купила ліцензію на БД Oracle. Потім у цю компанію я працевлаштувався. Відповідно почавши просувати .Net «в маси». БД Oracle використовуються не в багатьох організаціях, але використовують.
Як же здійснити взаємодію з БД Oracle, використовуючи C#? Обмовлюся заздалегідь, я не гуру Oracle; а так само не гуру гарного використання патернів, але я намагаюся і знаю де лежить пиріжок підходжу до питання філософськи, знаю що є, знаю, що я хочу, але використовую в необхідному мені ключі.
Але залишимо філософствування. Займемося завданням. Насамперед необхідно підготувати «середовище»: 1. Поставити клієнт Oracle, без якого взаємодію з БД не здійснити. 2. Налаштувати TNS для своїх потреб. 3. Створити проект у Visual Studio. 4. Додати reference на складанняSystem.Data.OracleClient.dll, за допомогою якої і «маніпулюватимемо» БД.
Підготуємо ґрунт, мабуть зробимо БД військкомату. У найпростішому випадку для цього вистачить однієї таблиці:
create table CONscript_INFO ( ID NUMBER not null, FIRST_NAME VARCHAR2(128), LAST_NAME VARCHAR2(128), AGES NUMBER, GROWTH FLOAT, BIOGRAPHY CLOB, >constraint PK_CONscript_INFO primary key (ID) );
Ідентифікатор, Ім'я, Прізвище, Вік, Зростання, Біографія. Вага нас не цікавить.
Визначимо процедури для додавання, на мій погляд найцікавіше, далі поясню чому:
PROCEDURE ADD_CONscript (FirstNameIn IN VARCHAR2, LastNameIn IN VARCHAR2, AgesIn IN NUMBER, GrowthIn IN FLOAT, BiographyIn IN CLOB) IS BEGIN INSERT INTO CONscript_INFO ( ID, FIRST_NAME, LAST_NAME, AGES, GROWTH, BIOGRAPHY ) VALUES ( CONscript_INFO_SEQ.NEXTVAL, FirstNameIn, LastNameIn, AgesIn, GrowthIn, BiographyIn ); END;
PROCEDURE DELETE_CONscript (ConscriptIDIn IN NUMBER) IS BEGIN
DELETE FROM CONscript_INFO WHERE > END;
PROCEDURE GET_CONscriptS (ConscriptsOut OUT sys_refcursor) IS BEGIN
OPEN ConscriptsOut FOR SELECT * FROM CONscript_INFO;
Тепер я поясню, що цікавого в процедурі додавання нового користувача є об'єкт типу CLOB. Цей тип здатний зберігати рядкові дані розміром до 4 гігабайт, на відміну від Varchar, здатного оперувати рядками до 4000 байт. Тобто. якщо ви спробуєте створити VARCHAR поле розміром 5000, отримаєте суворий «облом». Але ті хто працював з типом CLOB з C# знають, що це дуже «челябенськи». Але я забігаю вперед, про все гаразд.
При роботі з Oracle є один неприємний момент, якщо
не закривати з'єднання, то кількість курсорів буде після SELECT `a зростатиме в геометричній прогресії. Ця проблема вирішується «в лоб»:
Створення та відкриття з'єднання
using (OracleConnection connection = новий OracleConnection()) . >
таким чином, за вас всю чорнову роботу зробить IDisposable.
Якщо звернути увагу на конструктор
, то побачите що є два варіанти, «порожній» і з використанням рядка, що описує з'єднання з БД.
Рядок має приблизно такий вигляд:
Я думаю в поясненнях, що тут що, цей рядок не потребує.
Наступним кроком варто відкрити з'єднання:
Створення команди
Наразі ми готові виконувати команду. Після використання команди її теж необхідно «звільнити», не відходитимемо від принципів і скористаємося все тією ж чудовою конструкцією
using (OracleConnection connection = новий OracleConnection()) using (OracleCommand command = новий OracleCommand()) command.Connection = connection; command.CommandType = System.Data.CommandType.StoredProcedure; command.CommandText = "GET_CONscriptS"; > >
Давайте розберемося, що робить цей «шматок» коду: спочатку створюється команда, їй присвоюється з'єднання, в рамках якого працюватиме наша команда. Потім вказується тип команди, всього виділяється 3 типи:
1. StoredProcedure - Ім'я процедури, що зберігається.
2. TableDirect - Ім'я таблиці.
3. Text - Текстова команда SQL. (За замовчуванням).
Наступний параметр — текст, безпосередньо ім'я процедури, що зберігається, або команда. У нашому випадку буде використана процедура, що зберігається з ім'ям
Використання параметрів, що передаються
Обмовлюся відразу, використовувати параметри можна і з
нижче я покажу як це робиться.
Поки що повернемося з нашими параметрами:
OracleParameter ConscriptsOut = новий OracleParameter() ParameterName = "ConscriptsOut", Direction = System.Data.ParameterDirection.Output, OracleType = OracleType.Cursor >;
Що відбувається тут: створили параметр, вказали що він працює на «вихід» і вказали тип параметра (докладнішу інформацію про типи, що використовуються, а також їх сумісності зі стандартними типами .Net можна дізнатися з
). Якби параметр працював на «вхід», потрібно було б вказати і значення —
. Прикріпили параметр до команди та…
Виконання команди
команда виконана ... тепер можна "вигрібти" дані наприклад так:
DataTable table = New DataTable(); table.Load(command.Parameters["ConscriptsOut"].Value as OracleDataReader);
Повертається параметр,це курсор, який можна прочитати, як OracleDataReader. Як розбирати параметр залишимо як «домашнє завдання» ;).
На коня
На закінчення, я хочу розповісти про те, як передати параметр у текст, а точніше я покажу:
using (OracleConnection connection = новий OracleConnection()) using (OracleCommand command = новий OracleCommand()) command.Connection = connection; command.CommandType = System.Data.CommandType.Text; command.CommandText = @"SELECT * FROM CONscript_INFO WHERE AGES
Як бачите вся хитрість полягає у використанні знака -:.
У наступній статті я розповім про роботу з CLOB і наведу свій код, заточений під мене.