Частичные объекты в Oracle - PullRequest
       37

Частичные объекты в Oracle

1 голос
/ 11 марта 2012

Я использовал плоские хранимые процедуры (плоские средства не содержатся в объектах) в Oracle для обновления моих таблиц. Например, у меня есть таблица Person со столбцами Id, FirstName, LastName, Address, Salary. Я сделал плоскую процедуру Person_UpdFirstName, и эта процедура имеет два параметра: Id, FirstName. Внутри процедуры я нахожу строку в таблице Person, которая соответствует параметру Id, и обновляю FirstName с помощью параметра FirstName. Обычные вещи, ничего нового.

Теперь я использую объекты оракула. У меня есть объект PersonType, это UDT. Этот объект имеет те же поля, что и столбцы в таблице Person. Я поместил все процедуры, связанные с таблицей Person, в объект PersonType, то есть вместо простых процедур я начинаю использовать процедуры-члены. Ни одна из процедур-членов не имеет параметров, они принимают значения из полей объекта. Например, в случае плоской процедуры Person_UpdFirstName теперь у меня есть процедура-член UpdFirstName. Эта процедура-член не принимает никаких параметров, она использует поля Id и FirstName самого объекта и обновляет таблицу Person, как и раньше.

Проблема в том, что когда я использовал плоские процедуры, я передавал такие параметры, как Id, FirstName, поэтому в большой системе с сотнями таблиц я не могу ошибиться при передаче параметров в хранимую процедуру, поскольку число и тип параметров в каждой хранимой процедуре фиксируется. Теперь, когда я использую объекты, я должен помнить, какие поля объекта должны быть заполнены, в системе нет встроенной проверки. Это нормально, если поля в таблице Person не имеют значения NULL, потому что это в любом случае вызовет исключение, но если поля в таблице имеют значение NULL или когда я сравниваю значения, то у меня может быть много логических ошибок.

У меня вопрос, есть ли какой-нибудь встроенный способ закрыть эту дверь от потенциальных ошибок. У меня есть некоторые грубые решения, но я не уверен:

  1. Какие-то частичные объекты. Мои методы-члены должны быть вынуждены принимать в параметре эти частичные объекты. Например, у меня есть частичный объект PersonUpdFirstNameType, он имеет только одно поле FirstName, а затем мой метод-член UpdFirstName принимает это в качестве параметра. Конечно, это громоздко делать отдельный частичный тип для каждой операции над таблицей. Мне не очень нравится это решение
  2. Я не передаю объекты из c # процедурам оракула, вместо этого я передаю переменные в параметрах, а затем вручную строю (или не собираю) объекты оракула по мере необходимости.

Я нашел способ сопоставлять объекты оракула с классами c #. Для этого мне не нужно использовать какой-либо инструмент ORM. Мне просто нужно добавить несколько атрибутов в классы c # и поля c # этих классов и реализовать несколько интерфейсов. Таким образом, я могу передать объекты c # процедурам оракула и использовать "." синтаксис в процедурах оракула для доступа к полям, содержащим фактические данные.

Я думаю, что проблема, которую я задаю, является общей проблемой, поэтому она не относится к какому-либо конкретному языку. Общая проблема: предположим, у вас есть класс C с полями F1, F2, F3, F4, F5 и методами M1, M2, M3. M1 выполняет некоторые операции с некоторыми полями, M2 выполняет некоторые операции с некоторыми другими полями, M3 выполняет некоторые операции с некоторыми полями, на которые также могут воздействовать M1 или M2. Клиентский код создает объекты из C и может заполнить любое число (включая ноль) параметров перед вызовом любого метода. Что делать, если клиентский код вызывает метод перед помещением значений в поля, необходимые для метода. Я думаю, что в C # это обрабатывается компилятором путем генерирования исключений, если вы не инициализируете поля первыми; Вы также можете оставить поля пустыми в определении класса, такого как «int i», не помещая никакого значения в i, чтобы при вызове метода теперь компилятор выдавал исключение. В dbms такой поддержки нет из-за пустых полей. Если, скажем, вы сравниваете Id строки таблицы с Id поля объекта и забыли поместить какое-либо значение в поле объекта, то идентификатор строки таблицы сравнивается с нулем, и ни одна строка не сопоставляется и, следовательно, не обновляется. происходит (предположим, вы хотите обновить строки, которые соответствуют id, обычная операция обновления).

Я просто хочу знать, есть ли какая-либо встроенная проверка в системе для обработки таких случаев.

1 Ответ

1 голос
/ 12 марта 2012

Я не имею ни малейшего представления, как иметь ошибку во время компиляции , и я не знаю ни одного другого языка OO, который бы предоставлял такую ​​функцию (как компилятор может сказать, когда илигде атрибут был инициирован?)
Что вы можете сделать, это иметь исключения в время выполнения (что-то вроде NullPointerException или ArgumentNullException).
Например:

create or replace type person_o as object
(
  id    number,
  fname varchar2(32),
  lname varchar2(32),

  member procedure update_lname
);
/

create or replace type body person_o is

  member procedure update_lname is
  begin
    if self.lname is null then
      Raise_application_error(-20000, 'null attribute');
    end if;

    update persons_table set last_name = self.lname where id = self.id;
    commit;
  end;

end;
/
...