Ограничения
Ограничения являются средством, с помощью которого БД может принуждать к выполнению бизнес-правил и гарантировать что данные соответсвуют модели сущность-связь определённой системным анализом определяя структуры данных приложения. Например, бизнес-аналитик в компании решил что каждый покупатель и каждый заказ должен определяться уникальным числом, что нельзя создать заказ до создания покупателя и каждый заказ должен иметь валидную дату и сумму большую нуля. Это может быть достигнуто путём создания первичных ключей для столбца CUSTOMER_ID таблицы CUSTOMERS и столбца ORDER_ID таблицы ORDERS, создания внешнего ключа для таблица ORDERS ссылающегося на таблицу CUSTOMERS, создания ограничения “not null” для столбца ORDER_DATE (тип данных DATE сам проверит удовлятворяет ли введённое значение типа дата или нет) и ограничения проверки для столбца ORDER_AMOUNT таблицы ORDERS.
Если какой либо DML запрос к таблице с ограничениями нарушит ограничение, тогда весь запрос будет отменем автоматически. Надо помнить что DML запрос может обновлять много строк и частично обновление было успешным до нарушения ограничения для конкретной строки. Если запрос это часть транзакции состоящей из нескольких запросов, то результат выполнения запросов которые уже выполнились успешно остаётся но не подтверждённым.
A constraint violation will force an automatic rollback of the entire statement that hit the problem, not just the single action within the statement, and not the entire transaction.
Типы ограничений
Ограничения поддерживаемые Orace это
- UNIQUE
- NOT NULL
- PRIMARY KEY
- FOREIGN KEY
- CHECK
У ограничений есть имя. Хорошей практикой считается именовать их согласно конвенции имен, но если явно не указывать имя, Oracle будет использовать сгенерированное имя.
Ограничение уникальности
Ограничение уникальности назначает столбец (или группу столбцов) для которых значение должно быть разным для каждой строки в таблице. Если ограничение настроено для одного столбца, это называется столбец-ключ (key column). Если ограничение состоит из нескольких столбцов (называется составной ключ (composite key)), столбцы не должны быть одинакового типы и располагаться последовательно в таблице.
Странностью уникального ограничения можно считать возможность добавления значения NULL в столбцы ключа; более того можно иметь неограниченное количество строк со значение NULL в столбцах ключа. Таким образом запрос строк по ключу ограничения гарантирует одну строку для значения – пока не используется NULL, в таком случае все строки со значением NULL будут результатом запроса.
It is possible to insert many rows with NULLs in a column with a unique constraint. This is not possible for a column with a primary key constraint.
Ограничения уникальности работают с помощью индексов. Когда мы определяем ограничение, Oracle проверит существует ли индекс для столбцов ограничения, и если индекс не сущетвует, он будет создан. Затем когда происходи попытка вставки новой строки, Oracle просматривает индекс на существование значения ключа; если значение сущесвтует – строка будет отклонена. Индекс ограничения – B* Tree индекс, и он не хранит значения NULL, вот почему ограничение не работает для NULL (т.е. можно добавлять много строк со значением NULL). Как мы обсуждали выше, целью индексов является не только обеспечение работоспособности механизма ограничений, но и повышение производительности запросов с секцией WHERE и объединением таблиц. Если в запросе используется WHERE key_column IS NULL – Oracle не может использовать индекс (потому что индекс не хранит значения NULL) и всегда будет использовано полное чтение таблицы.
Ограничения NOT-NULL
Ограничения NOT-NULL принуждают указать данные для столбцов ключа. Эти ограничения накладываются на столбец и иногда их называют обязательными для заполнения столбцами (mandatory columns). Если несколько столбцов должны иметь значения, то вы не можете создать одно ограничение для группы – необходимо создавать ограничения для каждого столбца.
Любая попытка записи строки без указания значения для обязательного столбца вернёт ошибку. Возможно обойти эту проверку указав директиву DEFAULT при создании таблицы.
Первичный ключ
Первичный ключ является средством для поиска любой одной строки в таблице. Реляционная парадигма утверждает что каждая таблица должна иметь первичный ключ: столбец (или группу столбцов) которые можно использовать для выделения каждой строки. Oracle позволяет создавать таблицы (как и некоторые другие РСУБД) без первичного ключа.
Реализацией первичного ключа является комбинация ограничений целостности и обязательности. Значение в столбцах ключе должно быть уникальным и не NULL. Так же как и для ограничения уникальности индекс должен существовать для столбцов ключа, иначе он будет создан. У таблицы может быть только один первичный ключ. Но у таблицы может быть сколько угодно ограничений уникальности и not-null ограничений. Если у вас есть несколько столбцов которые должны быть уникальны и обязательны вы можете использовать часть из них для создания первичного ключа, а для остальных создать ограничения уникальности и обязательности. Например таблица сотрудников: все сотрудники должны иметь уникальный номер (первичный ключ) и также значения email, номер соц. страха должны быть уникальны и обязательны для заполнения.
Unique and primary key constraints need an index. If one does not exist, one will be created automatically.
Внешние ключи
Внешний ключ определяет отношение родитель-наследник. Это ограничение назначает столбец (или столбцы) в дочерней таблице которые должны соответствовать столбцу(ам) первичного ключа родительской таблицы. Соответствующие столбцы необязательно должны иметь одинаковые названия, но они должны быть одного типа данных. Внешний ключ определяет отношения один-ко-многим в третьей нормальной форме.
Если у родительской таблицы есть ограничение уникальности вместе (или вместо) первичного ключа, эти столбцы тоже могут использоваться как основа для внешнего ключа, даже если они не обязательны (nullable).
A foreign key constraint is defined on the child table, but a unique or primary key constraint must already exist on the parent table.
Как и ограничение уникальности внешний ключ допускает значение NULL в столбцах ключа. Вы можете вставить строки в дочернюю таблицу со значением NULL в столбцах внешнего ключа – даже если в родительской таблице нет строки со значением NULL. Это создаст строки призраки (orphaned rows) и может вызвать определённые недоразмения. Как правило все столбцы ограничения уникальности и все столбцы внешнего ключа лучше определять вместе с ограничениями not-null: так же это обычно требование бизнеса.
При попытки вставить строку в дочернюю таблицу со значением ключа которого нет в родительской таблице – произойдёт ошибка выполнения запроса. Также попытка удаления строки в родительской таблице вернёт ошибку если существуют строки в дочерней которые ссылаются на эту строке. Существует два способа обойти это ограничение. Во-первых, ограничения могут быть созданы с директивой ON DELETE CASCADE. Это значит что если мы удаляется строка из родительской таблицы – Oracle автоматически найдёт все строки ссылающиеся на эту строку в дочерней таблице и удалит их тоже. Менее кардинальный способ – использование директивы ON DELETE SET NULL. В этом случае если строка родительской таблицы удаляется – Oracle найдёт все соответствующие строки в дочерней таблице и установит значение ключа в NULL. Это значит что строки в дочерней таблице станут строками-призраками – но они будут существовать в таблице. Если столбцы внешнего ключа имеют ограничение not-null – то удаление из родительской таблицы вернёт ошибку. Нельзя ни удалить ни выполнить операцию TRUNCATE для родительской таблицы, даже если нет ни одной строки в дочерней таблице. Даже если использованы ON DELETE SET NULL или ON DELETE CASCADE.
Отдельным видом внешнего ключа является внешний ключ ссылающийся сам на себя (self-referencing). Такой ключ определяет отношение где родительский и дочернии строки находятся в одной таблице. Хорошим примером является таблица сотрудников, в которой есть столбец MANAGER_ID. И менеджер и сотрудник являются сотрудниками. Если первичный ключ EMPLOYEE_ID то для внешнего ключа используем EMPLOYEE_ID как родительский столбец и MANAGER_ID как дочерний. Если у сотрудника нет менеджера, то такая строка указывает сама на себя.
Ограничения проверки значения (Check constraints)
Ограничения проверки значения используются для проверки данных на удовлетворение простым правилам, к примеру введённое значение должно попадать в период значений. Правилом должно быть выражение результатом проверки которого будет либо ПРАВДА либо ЛОЖЬ. Правила могут использовать литералы, или другие столбцы той же строки и они могут использовать некоторые функции. Сколько угодно правил можно применить к одному ограничение проверки значения, но нельзя использовать подзапросы или такие функции как SYSDATE.
The not-null constraint is in fact implemented as a preconfigured check constraint.
Определение ограничений
Ограничение можно определить при создании таблицы или добавить позже. При создании таблицы, ограничения можно указать в строке определяющей столбец используемые в ограничении, либо в конце оператора создания таблицы. В конце оператора создания вы можете определять ограничения более гибко. В строке определения столбца вы не можете создать ограничение использующее другие столбцы таблицы. При определении ограничения требующего индекс в момент создания таблицы также создастся индекс.
Расмотрим два запроса создания таблицы
1 create table dept(
2 deptno number(2,0) constraint dept_deptno_pk primary key
3 constraint dept_deptno_ck check (deptno between 10 and 90),
4 dname varchar2(20) constraint dept_dname_nn not null);
5 create table emp(
6 empno number(4,0) constraint emp_empno_pk primary key,
7 ename varchar2(20) constraint emp_ename_nn not null,
8 mgr number (4,0) constraint emp_mgr_fk references emp (empno),
10 hiredate date,
11 deptno number(2,0) constraint emp_deptno_fk references dept(deptno)
12 on delete set null,
13 email varchar2(30) constraint emp_email_uk unique,
14 constraint emp_hiredate_ck check (hiredate >= dob + 365*16),
15 constraint emp_email_ck
- Первая таблица создаётся с именем DEPT и предназначена для хранения одной строки для каждого департамента.
- DEPTNO – числовое поле, 2 цифры, нет точек после запятой. Первичный ключ таблицы – имя ограничения DEPT_DEPTNO_PK.
- Второе ограничение столбца DEPTNO это проверка значения на период от 10 до 90. Имя этого ограничения DEPT_DEPTNO_CK.
- Столбец DNAME – это строка нефиксированной длины, обязательна для заполнения – ограничение DEPT_DNAME_NN.
- Вторая табилца это EMP, предназаченная для хранения строки для каждого сотрудника.
- Столбец EMPNO типа данных NUMERIC, 4 цифры без дробной части первичный ключ EMP_EMPNO_PK. ENAME
- Столбец ENAME строка произвольной длины до 20 символов с not null ограничением EMP_ENAME_NN
- Столбец MGR определён так же как и EMPNO плюс является внешним ключом таблицы к самой себе по полям MGR-EMP_NO. Нет ограничения на not-null поэтому может быть NULL
- DOB – дата рождения сотрудника, тип данных дата нет ограничений
- HIREDATE – дата приёма на работу, нет ограничений
- DEPTNO департамент, определение столбца такое же как столбец DEPTNO таблицы DEPT. Внешний ключ к таблице департаментов: нельзя вставить строку со значением которого нет в таблице DEPT. Но значение может быть
- Внешний ключ EMP_DEPTO_FK определён с директивой ON DELETE SET NULL, т.е. при удалении строки из таблицы DEPT значение столбца DEPTNO во всех относящиеся к удаляемой строке будет обновлено в значение NULL.
- EMAIL – строка переменной длины и имеет ограничение уникальности (но может быть NULL)
- Определение дополнительного ограничения EMP_HIREDATE_CK. Дата приёма на работу должна быть не раньше чем 16 лет после даты рождения. Данное ограничение невозможно создать в строке определения столбца HIREDATE, так как ограничение ссылается на другой столбец
- Определение дополнительного ограничения проверки значения для строки EMAIL. Вызываются функции которые проверяют наличие @ и “.” в значении и если хотя бы одна функция вернёт ЛОЖЬ то строка будет отклонена.
Эти примеры показывают некоторые возможности определения ограничения при создании таблицы. Остальные возможности это
Управление созданием индексов для внешних ключей и ограничений уникальности
Определение времени проверки ограничения: во время вставки (значение по умолчанию) или позже, в момент подтверждения транзакции
Включено ли ограничение (по умолчанию) или отключено
Возможно создать таблицу без ограничений а затем добавить ограничения командой ALTER TABLE. Результат будет одинаковый но определение таблицы будет разбито на несколько запросов вместо одного.
Состояния ограничений
В любой момент времени, каждое ограничение включено или выключена и проверяется или не проверяется. Любая комбинация этих двух состояний возможна
- ENABLEVALIDATE – Невозможно добавить строку которая нарушает ограничение и все строки таблицы удовлетворяют ограничениям
- DISABLENOVALIDATE – Любые данные возможно ввести и в таблицу уже могут быть данные нарушающие ограничения
- ENABLENOVALIDATE – В таблице могут существовать данные не удовлетворяющие ограничениям, но все добавляемые данные должны удовлетворять ограничениям
- DISABLEVALIDATE – невозможная ситуация: все данные в таблице удовлетворяют ограничениям, но новые данные должны неудовлетворять. Т.е. нельзя вставить данные в таблицу.
Идеальной ситуацией (и состоянием по умолчанию при определении ограничения) является ENABLE VALIDATE. Это гарантирует что данные корректны и некорректные данные не могут быть добавлены.
Статус DISABLE NOVALIDATE полезен когда загружается много данных в таблицу одним запросом. Данные могут содержать плохие значения, но вместо ошибки выполнения запроса этот статус позволит загрузить данные. Сразу после загрузки данных, переведите состояние в ENABLE NOVALIDATE чтобы предотвратить вставку других неправильных данных пока вы будете проверять уже добавленные данные на удовлетворение ограничениям. И затем опять установите правильное состояние ENABLE VALIDATE.
Примером такой задачи может быть скрипт, читающий данные из активных данных в архив. Преположим что есть ограничение NOT-NULL на столбце архивной таблицы, которого нет у столбца активной
alter table sales_archive modify constraint sa_nn1 disable novalidate;
insert into sales_archive select * from sales_current;
alter table sales_archive modify constraint sa_nn1 enable novalidate;
update sales_archive set channel=’NOT KNOWN’ where channel is null;
alter table sales_archive modify constraint sa_nn1 enable validate;
Проверка ограничений
Ограничения могут проверятся на момент выполнения запроса (ограничение IMMEDIATE) или когда подтверждается вся транзакция (DEFERRED). По умолчанию все ограничения в режиме IMMEDIATE. Это может быть альтернативой использования состояний. Можно переписать скрипт из подпункта «Состояние ограничений» таким образом
set constraint sa_nn1 deferred;
insert into sales_archive select * from sales_current;
update sales_archive set channel=’NOT KNOWN’ where channel is null;
set constraint sa_nn1 immediate;
Для поддержки отложенного (DEFERRED) ограничения оно должно быть создано используя синтаксис
alter table sales_archive add constraint sa_nn1
check (channel is not null) deferrable initially immediate;
То есть невозможно сделать ограничение отложенным если директива deferrable не была указана при создании. В нашем случае ограничение SA_NN1 по умолчанию проверяется на момент вставки строки (или изменения), но проверку можно отложить до подтверждения транзакции. Часто отложенные ограничения используются для внешних ключей. Если операции обновления и изменения затрагивают и дочернюю и родительскую таблицу, и если внешний ключ не отложенный то операция может выполниться с ошибкой в зависимости от порядка обработки строк.
Изменение состояния ограничения затрагивает все сессии. Изменение времени проверки ограничения (IMMEDIATE или DEFERRED) затрагивает текущую сессию, но начальное состояние применяется ко всем сессиям.
By default, constraints are enabled and validated, and they are not deferrable.
Building Database Objects
This section describes specifications for how to define your tables and the required columns to add. It also covers special data types such as LONG and LONG RAW, and declarative constraints.
Using Cost-Based Optimization
Oracle E-Business Suite uses Oracle Cost-Based Optimization (CBO) instead of the Rule-Based Optimization (RBO) used in previous versions. All new code should be written to take advantage of Cost-Based Optimization. Where your custom application code was tuned to take advantage of Rule-Based Optimization, you may need to retune that code for Cost-Based Optimization.
For additional information, refer to the Oracle database tuning documentation.
Tracking Data Changes with Record History (WHO)
The Record History (WHO) feature reports information about who created or updated rows in Oracle E-Business Suite tables. Oracle E-Business Suite upgrade technology relies on Record History (WHO) information to detect and preserve customizations.
If you add special WHO columns to your tables and WHO logic to your forms and stored procedures, your users can track changes made to their data. By looking at WHO columns, users can differentiate between changes made by forms and changes made by concurrent programs.
You represent each of the WHO columns as hidden fields in each block of your form (corresponding to the WHO columns in each underlying table). Call FND_STANDARD.SET_WHO in PRE-UPDATE and PRE-INSERT to populate these fields.
Adding Record History Columns
The following table lists the standard columns used for Record History (WHO), the column attributes and descriptions, and the sources for the values of those columns. Set the CREATED_BY and CREATION_DATE columns only when you insert a row (using FND_STANDARD.SET_WHO for a form).
| Column Name | Type | Null? | Foreign Key? | Description | Value |
|---|---|---|---|---|---|
| CREATED_BY | NUMBER(15) | NOT NULL | FND_ USER | Keeps track of which user created each row | TO_NUMBER (FND_ PROFILE. VALUE (‘USER_ID’)) |
| CREATION_ DATE | DATE | NOT NULL | Stores the date on which each row was created | SYSDATE | |
| LAST_ UPDATED_BY | NUMBER(15) | NOT NULL | FND_ USER | Keeps track of who last updated each row | TO_NUMBER (FND_ PROFILE. VALUE (‘USER_ID’)) |
| LAST_UPDATE_ DATE | DATE | NOT NULL | Stores the date on which each row was last updated | SYSDATE | |
| LAST_UPDATE_ LOGIN | NUMBER(15) | FND_ LOGINS | Provides access to information about the operating system login of the user who last updated each row | TO_NUMBER (FND_ PROFILE. VALUE (‘LOGIN_ ID’)) |
Any table that may be updated by a concurrent program also needs additional columns. The following table lists the concurrent processing columns used for Record History, the column attributes and descriptions, and the sources for the values of those columns.
| Column Name | Type | Null? | Foreign Key to Table? | Description |
|---|---|---|---|---|
| REQUEST_ID | NUMBER(15) | FND_ CONCURRENT_ REQUESTS | Keeps track of the concurrent request during which this row was created or updated | |
| PROGRAM_ APPLICATION_ ID | NUMBER(15) | FND_ CONCURRENT_ PROGRAMS | With PROGRAM_ID, keeps track of which concurrent program created or updated each row | |
| PROGRAM_ID | NUMBER(15) | FND_ CONCURRENT_ PROGRAMS | With PROGRAM_ APPLICATION_ID, keeps track of which concurrent program created or updated each row | |
| PROGRAM_ UPDATE_DATE | DATE | PROGRAM_ UPDATE_ DATE | Stores the date on which the concurrent program created or updated the row |
Use Event Handlers to Code Record History in Your Forms
Some operations that must be done at commit time do not seem designed for a table handler. For example, event handlers are preferred to table handlers for setting Record History information for a record, or determining a sequential number. The logic for these operations may be stored in a PRE_INSERT and/or PRE_UPDATE event handler, which is called from PRE-INSERT and PRE-UPDATE block-level triggers during inserts or updates.
Property Classes For WHO Fields
Apply the CREATION_OR_LAST_UPDATE_DATE property class to the form fields CREATION_DATE and LAST_UPDATE_DATE. This property classes sets the correct attributes for these fields, including the data type and width.
Record History Column Misuse
Never use Record History columns to qualify rows for processing. Never depend on these columns containing correct information.
In general, you should not attempt to resolve Record History columns to HR_EMPLOYEES; if you must attempt such joins, they must be outer joins.
Tables Without Record History Information
For blocks that are based on a table, but do not have Record History information, disable the menu entry HELP->ABOUT_THIS_RECORD (all other cases are handled by the default menu control).
Code a block-level WHEN-NEW-BLOCK-INSTANCE trigger (style «Override») with these lines:
Oracle Declarative Constraints
This section discusses the declarative constraints the Oracle database permits on tables, and when to use each feature with your Oracle E-Business Suite tables.
For the most part, any constraint that is associated with a table should be duplicated in a form so that the user receives immediate feedback if the constraint is violated.
Warning: You should not create additional constraints on Oracle E-Business Suite tables at your site, as you may adversely affect Oracle E-Business Suite upgrades. If you do create additional constraints, you may need to disable them before upgrading Oracle E-Business Suite.
NOT NULL
Use wherever appropriate. Declare the corresponding fields within Oracle Forms as «Required» = True.
DEFAULT
In general, do not use this feature due to potential locking problems with Oracle Forms. You may be able to use this feature with tables that are not used by forms (for example, those used by batch programs), or tables that contain columns that are not maintained by forms. For example, defaulting column values can make batch programs simpler. Possible default values are SYSDATE, USER, UID, USERENV(), or any constant value.
UNIQUE
Use wherever appropriate. A unique key may contain NULLs, but the key is still required to be unique. The one exception is that you may have any number of rows with NULLS in all of the key columns.
In addition, to implement a uniqueness check in a form, create a PL/SQL stored procedure which takes ROWID and the table unique key(s) as its arguments and raises an exception if the key is not unique. Only fields that the user can enter should have a uniqueness check within the form; system-generated unique values should be derived from sequences which are guaranteed to be unique.
CHECK
Use this feature to check if a column value is valid only in simple cases when the list of valid values is static and short (i.e., ‘Y’ or ‘N’).
CHECK provides largely duplicate functionality to database triggers but without the flexibility to call PL/SQL procedures. By using triggers which call PL/SQL procedures instead, you can share constraints with forms and coordinate validation to avoid redundancy.
CHECK does provide the assurance that all rows in the table will pass the constraint successfully, whereas database triggers only validate rows that are inserted/updated/deleted while the trigger is enabled.
This is not usually a concern, since Oracle E-Business Suite database triggers should rarely be disabled. Some triggers (such as Alert events) are disabled before an upgrade and re-enabled at the end of the upgrade.
We strongly advise against the use of database triggers.
PRIMARY KEY
Define a Primary Key for all tables.
Cascade Delete and Foreign Key Constraint
Do not use the Declarative Cascade Delete or the Foreign Key Constraint when defining tables. Cascade Delete does not work across distributed databases, so you should program cascade delete logic everywhere it is needed.
To implement a referential integrity check, create a PL/SQL stored procedure which takes the table unique key(s) as its argument(s) and raises an exception if deleting the row would cause a referential integrity error.
LONG, LONG RAW and RAW Datatypes
Avoid creating tables with the LONG, LONG RAW, or RAW datatypes. Within Oracle Forms, you cannot search using wildcards on any column of these types. Use VARCHAR2(2000) columns instead.
Columns Using a Reserved Word
If a table contains a column named with a PL/SQL or an Oracle Forms reserved word, you must create a view over that table that aliases the offending column to a different name. Since this view does not join to other tables, you can still INSERT, UPDATE, and DELETE through it.
Views
In general, complex blocks are based on views while simple setup blocks are based on tables. The advantages to using views include:
Network traffic is minimized because all foreign keys are denormalized on the server
You do not need to code any POST-QUERY logic to populate non-database fields
You do not need to code PRE-QUERY logic to implement query-by-example for non-database fields
You should also base your Lists of Values (LOVs) on views. This allows you to centralize and share LOV definitions. An LOV view is usually simpler than a block view, since it includes fewer denormalized columns, and contains only valid rows of data.
Define Views To Improve Performance
Whenever performance is an issue and your table has foreign keys, you should define a view to improve performance. Views allow a single SQL statement to process the foreign keys, reducing parses by the server, and reducing network traffic.
Define Views to Promote Modularity
Any object available in the database promotes modularity and reuse because all client or server side code can access it. Views are extremely desirable because:
They speed development, as developers can build on logic they already encapsulated
They modularize code, often meaning that a correction or enhancement can be made in a single location
They reduce network traffic
They are often useful for reporting or other activities
They can be easily and centrally patched at a customer site
When Not to Create A View
Avoid creating views that are used by only one SQL statement. Creating a view that is only used by a single procedure increases maintenance load because both the code containing the SQL statement and the view must be maintained.
ROW_ID Is the First Column
The first column your view should select is the ROWID pseudo-column for the root table, and the view should alias it to ROW_ID. Your view should then include all of the columns in the root table, including the WHO columns, and denormalized foreign key information.
Tip: You only need to include the ROWID column if an Oracle Forms block is based on this view. The Oracle Forms field corresponding to the ROW_ID pseudo-column should use the ROW_ID property class.
Change Block Key Mode
In Oracle Forms, you need to change the block Key Mode property to Non-Updatable to turn off Oracle Forms default ROWID references for blocks based on views. Specify the primary keys for your view by setting the item level property Primary Key to True.
For example, a view based on the EMP table has the columns ROW_ID, EMPNO, ENAME, DEPTNO, and DNAME. Set the Key Mode property of block EMP_V to Non-Updatable, and set the Primary Key property of EMPNO to True.
If your block is based on a table, the block Key Mode should be Unique.
Code Triggers for Inserting, Updating, Deleting and Locking
When basing a block on a view, you must code ON-INSERT, ON-UPDATE, ON-DELETE, and ON-LOCK triggers to insert, update, delete, and lock the root table instead of the view.
Single Table Views
Single table views do not require triggers for inserting, updating, deleting and locking. Set the block Key Mode to Unique. Single table views do not require a ROW_ID column.
Special Characters
Do not use the CHR() function (used to define a character by its ASCII number) on the server side. This causes problems with server-side platforms that use EBCDIC, such as MVS. You should not need to embed tabs or returns in view definitions.
Sequences
This section discusses standards for creating and using sequences.
Create Single Use Sequences
Use each sequence to supply unique ID values for one column of one table.
Do Not Limit the Range of Your Sequences
Do not create sequences that wrap using the CYCLE option or that have a specified MAXVALUE. The total range of sequences is so great that the upper limits realistically are never encountered.
In general, do not design sequences that wrap or have limited ranges.
Use Number Datatypes to Store Sequence Values
Use a NUMBER datatype to store sequence values within PL/SQL.
If you need to handle a sequence generate a sequence value in your C code, do not assume that a sequence-generated value will fit inside a C long variable. The maximum value for an ascending sequence is 10^27, whereas the maximum value for a C signed long integer is 10^9. If 10^9 is not a reasonable limit for your sequence, you may use a double instead of a long integer. Remember that by using a double for your sequence, you may lose some precision on fractional values. If you do not need to do arithmetic, and simply need to fetch your sequence either to print it or store it back, consider retrieving your sequence in a character string.
Do Not Use the FND_UNIQUE_IDENTIFIER_CONTROL Table
Do not rely on the FND_UNIQUE_IDENTIFIER_CONTROL table to supply sequential values. Use a sequence or the sequential numbering package instead. The FND_UNIQUE_IDENTIFIER_CONTROL table is obsolete and should not have any rows for objects in your product.
Additionally, do not create application-specific versions of the FND table to replace the FND_UNIQUE_IDENTIFIER_CONTROL table.
Table Registration API
You register your custom application tables using a PL/SQL routine in the AD_DD package.
Flexfields and Oracle Alert are the only features or products that depend on this information. Therefore you only need to register those tables (and all of their columns) that will be used with flexfields or Oracle Alert. You can also use the AD_DD API to delete the registrations of tables and columns from Oracle Application Object Library tables should you later modify your tables.
If you alter the table later, then you may need to include revised or new calls to the table registration routines. To alter a registration you should first delete the registration, then reregister the table or column. You should delete the column registration first, then the table registration.
You should include calls to the table registration routines in a PL/SQL script. Though you create your tables in your own application schema, you should run the AD_DD procedures against the APPS schema. You must commit your changes for them to take effect.
The AD_DD API does not check for the existence of the registered table or column in the database schema, but only updates the required AOL tables. You must ensure that the tables and columns registered actually exist and have the same format as that defined using the AD_DD API. You need not register views.
Procedures in the AD_DD Package
| Variable | Description |
|---|---|
| p_appl_short_ name | The application short name of the application that owns the table (usually your custom application). |
| p_tab_name | The name of the table (in uppercase letters). |
| p_tab_type | Use ‘T’ if it is a transaction table (almost all application tables), or ‘S’ for a «seed data» table (used only by Oracle E-Business Suite products). |
| p_pct_free | The percentage of space in each of the table’s blocks reserved for future updates to the table (1-99). The sum of p_pct_free and p_pct_used must be less than 100. |
| p_pct_used | Minimum percentage of used space in each data block of the table (1-99). The sum of p_pct_free and p_pct_used must be less than 100. |
| p_col_name | The name of the column (in uppercase letters). |
| p_col_seq | The sequence number of the column in the table (the order in which the column appears in the table definition). |
| p_col_type | The column type (‘NUMBER’, ‘VARCHAR2’, ‘DATE’, etc.). |
| p_col_width | The column size (a number). Use 9 for DATE columns, 38 for NUMBER columns (unless it has a specific width). |
| p_nullable | Use ‘N’ if the column is mandatory or ‘Y’ if the column allows null values. |
| p_translate | Use ‘Y’ if the column values will be translated for an Oracle E-Business Suite product release (used only by Oracle E-Business Suite products) or ‘N’ if the values are not translated (most application columns). |
| p_next_extent | The next extent size, in kilobytes. Do not include the ‘K’. |
| p_precision | The total number of digits in a number. |
| p_scale | The number of digits to the right of the decimal point in a number. |
Example of Using the AD_DD Package
Here is an example of using the AD_DD package to register a flexfield table and its columns:
XML Definition File Utility
The XDF (XML Definition File) is the next generation version of the current ODF (Object Definition File) utility which is used to propagate object definitions from Oracle to customer sites.
Note that XDF currently does not support «alters» for nested tables; Only «create» scenarios for nested tables is supported. In Release 12.1, XDF can capture the nested table information in the XDF file, read this information while propagating the table object, and alter the base table to include this nested table column.
Per Oracle E-Business Suite standards, there cannot be two primary keys on a table both with the primary key type as ’D’. In Release 12.1, the XDF application will, depending on a specified parameter value, overwrite the old primary key and create a new one in the XDF file.
Object Containment in XDF
The ADODFGEN utility relied on the concept of building blocks to generate ODF(s). XDF does not support the concept of building blocks and instead groups a primary object along with its dependent objects to allow for a blend of granularity, ease of maintenance, and efficient comparison. The following table provides details on object containment:
Oracle nullable and non nullable column in a view
I have a table in Oracle. This table has amongst others: EMPLOYEE_ID (NUMBER, Nullable, but number of NULLs is 0) and EMPLOYEE_NUMBER (VARCHAR2, Nullable, but number of NULLs is 0).
Now I create a view on this table:
How on earth is it possible that in that view PERSON_ID becomes Nullable (even when using NVL trick), but EMPLOYEE_NUMBER is NOT Nullable
QUESTION: How can I make Oracle to create the view in a way, so the PERSON_ID column becomes NOT Nullable in the view? Or how can I make my WCF oData service query this view. Currently after updating the edmx file I get the following: