Oracle SQL создает столбец идентификаторов во вложенной таблице

Я делаю таблицу, которая содержит вложенную таблицу:

create DOCUMENT as OBJECT (
    DOC_ID NUMBER,
    DESCRIPTION VARCHAR(1000));   

create type documents_t is table of DOCUMENT;

create table projects (
    ID NUMBER GENERATED ALWAYS AS IDENTITY ,
    DOCUMENTS documents_t)
    NESTED TABLE DOCUMENTS STORE AS documents_nested(
        (PRIMARY KEY(nested_table_id, DOC_ID)) ORGANIZATION INDEX);

Это работает нормально, но я не могу найти, как сделать первичный ключ вложенной таблицы столбцом идентификации. какие-либо предложения? Спасибо


person Izik    schedule 22.07.2020    source источник
comment
Вы только ищете решение с созданием идентификатора вложенной таблицы в качестве столбца идентификации?   -  person Sujitmohanty30    schedule 22.07.2020
comment
Да, мне нужно, чтобы столбец первичного ключа во вложенной таблице (столбец DOC_ID) также был столбцом идентификации.   -  person Izik    schedule 22.07.2020
comment
Я имею в виду, что не нахожу таких возможностей. мы можем добиться того же с помощью пользовательского конструктора и использования последовательности. если хотите, могу привести один пример.   -  person Sujitmohanty30    schedule 22.07.2020
comment
Вы имеете в виду использование как конструктора, так и последовательности? или я могу сделать это только с помощью конструктора?   -  person Izik    schedule 22.07.2020
comment
Только с конструктором, но с использованием последовательности внутри него для генерации значения для идентификатора.   -  person Sujitmohanty30    schedule 22.07.2020
comment
Спасибо, буду рад увидеть пример   -  person Izik    schedule 22.07.2020


Ответы (2)


Пожалуйста, найдите фрагмент кода,

CREATE SEQUENCE seq_documents
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;

CREATE OR REPLACE TYPE documents_q AS OBJECT
(
   doc_id      NUMBER,
   description VARCHAR2(1000),
   CONSTRUCTOR FUNCTION documents_q(p_description VARCHAR2) RETURN SELF AS RESULT
);

CREATE OR REPLACE TYPE BODY documents_q AS
   CONSTRUCTOR FUNCTION documents_q(p_description VARCHAR2) RETURN SELF AS RESULT IS
   BEGIN
      self.doc_id      := seq_documents.nextval;
      self.description := p_description;
      RETURN;
   END;
END;
/

CREATE TYPE documents_t AS TABLE OF documents_q;

create table projects (
    id NUMBER GENERATED ALWAYS AS IDENTITY ,
    documents documents_t)
    NESTED TABLE documents STORE AS documents_nested(
        (PRIMARY KEY(nested_table_id, doc_id))  ORGANIZATION INDEX);

INSERT INTO PROJECTS(documents) VALUES (documents_t(documents_q('Description One'),documents_q('Description Two')));
        
SELECT * FROM projects;

Пожалуйста, дайте мне знать, если это даст вам решение. Спасибо

person Sujitmohanty30    schedule 22.07.2020
comment
Большое спасибо за пример. это работает. Хотя я хотел, чтобы Oracle сделал это проще. - person Izik; 23.07.2020
comment
Не за что:). Да, мы должны продолжать искать такое решение, уже доступное в Oracle, и обновлять его здесь. - person Sujitmohanty30; 23.07.2020

Если вам нужно другое решение без конструктора (потому что использование конструктора добавляет больше обслуживания)

Я взял идею @Sujitmohanty30 и использовал последовательность в операторе вставки. Это упрощает поддержку кода, но вынуждает вас использовать последовательность при вставке и вставлять один элемент в каждый запрос (поскольку sequence.nextval не увеличивается в одном и том же запросе):

CREATE SEQUENCE documents_seq NOCACHE;
/
CREATE TYPE document_type AS OBJECT (
   doc_id      NUMBER,
   description VARCHAR2(1000)
);
/
CREATE TYPE documents AS TABLE OF document_type;
/
create table projects_docs (
    id NUMBER GENERATED ALWAYS AS IDENTITY ,
    docs documents)
    NESTED TABLE docs STORE AS docs_nested(
        (PRIMARY KEY(nested_table_id, doc_id)) ORGANIZATION INDEX); 
 /
INSERT INTO projects_docs (docs) VALUES(
    documents(document_type(documents_seq.nextval, 'doc')));
/
select p.id, d.* from projects_docs p, table(p.docs) d;
person Izik    schedule 23.07.2020