Вставить данные во вложенную таблицу

Могу ли я получить помощь, чтобы вставить значения в таблицу. Таблица называется PurchaseOrder_objtab. Вот тип таблицы:

CREATE TYPE PurchaseOrder_objtyp AUTHID CURRENT_USER AS OBJECT
(
  PONo NUMBER,
  CUST_ref REF Customer_objtyp,
  OrderDate DATE,
  ShipDate DATE,
  LineItemList_ntab LineItemList_ntabtyp,
  ShipToAddr_obj Address_objtyp
)
/

LineItemList_ntab — это вложенная таблица.

Вот код создания LineItemList_ntabtyp:

CREATE TYPE LineItem_objtyp AS OBJECT (
  LineItemNo NUMBER,
  Stock_ref REF StockItem_objtyp,
  Quantity NUMBER,
  Discount NUMBER
)
/

CREATE TYPE LineItemList_ntabtyp AS TABLE of LineItem_objtyp
/

Вот код вставки, который работает:

INSERT INTO PurchaseOrder_objtab
SELECT 1008, REF(C),
SYSDATE, '12-MAY-1999',
LineItemList_ntabtyp(),
NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

В приведенном выше коде LineItemList_ntab является пустым LineItemList_ntabtyp. Я хочу добавить значения в эту вложенную таблицу, а не пустую в коде INSERT INTO.

Вот часть кода, который я пытался вставить в значения:

INSERT INTO PurchaseOrder_objtab
SELECT 1008, REF(C),
SYSDATE, '12-MAY-1999',
LineItemList_ntabtyp(1, REF(StckItem), 10, 1) FROM Stock_objtab StckItem WHERE StckItem.StockNo = 1004,
NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

INSERT INTO PurchaseOrder_objtab
SELECT 1008, REF(C),
SYSDATE, '12-MAY-1999',
INSERT INTO LineItemList_ntab SELECT 1, REF(StckItem),10,1 FROM Stock_objtab StckItem WHERE StckItem.StockNo = 1004, 
NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

Первый оператор вставки выше приводит к следующей ошибке:

Ошибка SQL: ORA-00933: команда SQL неправильно завершена

Второй оператор вставки выше приводит к следующей ошибке:

Ошибка SQL: ORA-00936: отсутствует выражение

Могу ли я получить помощь, чтобы успешно вставить значения во вложенную таблицу LineItemList_ntab?

ОБНОВЛЕНИЕ

У меня есть этот код для вставки данных:

INSERT INTO PurchaseOrder_objtab
SELECT 
1008, 
REF(C),
SYSDATE, 
'12-MAY-1999',
(SELECT LineItemList_ntabtyp(LineItem_objtyp(1, REF(StckItem), 10, 1)) FROM Stock_objtab StckItem WHERE StckItem.StockNo = 1004),
NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

Теперь я получаю следующую ошибку:

Ошибка SQL: ORA-22979: невозможно ВСТАВИТЬ ссылку на представление объекта или определенную пользователем ссылку 22979. 00000 — «невозможно ВСТАВИТЬ ссылку на представление объекта или определенную пользователем ссылку» * Причина: попытка вставить ссылку на представление объекта или определенную пользователем ссылку в Столбец REF, созданный для хранения сгенерированных системой значений REF" *Действие: Убедитесь, что REF, который нужно вставить, не из представления объекта или из пользовательского столбца REF

Я почти уверен, что эта ошибка связана с тем, что я, возможно, неправильно создал таблицу, вот мой код создания таблицы для PurchaseOrder_objtab:

CREATE TABLE PurchaseOrder_objtab OF PurchaseOrder_objtyp(
PRIMARY KEY (PONo),
FOREIGN KEY (Cust_ref) REFERENCES Customer_objtab)
OBJECT ID PRIMARY KEY

  NESTED TABLE LineItemList_ntab STORE AS PoLine_ntab(
(PRIMARY KEY(NESTED_TABLE_ID, LineItemNo))
ORGANIZATION INDEX COMPRESS)
RETURN AS LOCATOR
/

Вот код для создания вложенной таблицы:

CREATE TYPE LineItemList_ntabtyp AS TABLE of LineItem_objtyp
/

ОБНОВЛЕНИЕ 2

Этот код успешно добавляет информацию в таблицу:

INSERT INTO PurchaseOrder_objtab
SELECT 1009, REF(C),
SYSDATE, '10-MAY-1999',
LineItemList_ntabtyp(),
NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

Так что ошибка как-то связана с LineItemList_ntabtyp.

Вот код создания таблицы:

CREATE TABLE PurchaseOrder_objtab OF PurchaseOrder_objtyp(
PRIMARY KEY (PONo),
FOREIGN KEY (Cust_ref) REFERENCES Customer_objtab)
OBJECT ID PRIMARY KEY

NESTED TABLE LineItemList_ntab STORE AS PoLine_ntab((PRIMARY KEY(NESTED_TABLE_ID,LineItemNo)) ORGANIZATION INDEX COMPRESS) RETURN AS LOCATOR/

Я уверен, что ошибка имеет какое-то отношение к ОБЪЕКТУ IDENTIFIER IS PRIMARY KEY для приведенной выше таблицы.

ОБНОВЛЕНИЕ 3

Спасибо за код. Как насчет вставки более одного значения во вложенную таблицу.

Ваша строка кода для одного элемента:

(SELECT LineItemList_ntabtyp(LineItem_objtyp(1, REF(StckItem), 10, 1)) FROM Stock_objtab WHERE StockNo = 1004),
NULL)

Как насчет того, чтобы добавить два товара, оба со складскими номерами 1004 и 1005? Это что-то вроде этого:

(SELECT LineItemList_ntabtyp(LineItem_objtyp(1, REF(StckItem), 10, 1)) FROM Stock_objtab WHERE StockNo = 1004) AND (SELECT LineItemList_ntabtyp(LineItem_objtyp(2, REF(StckItem), 10, 1)) FROM Stock_objtab WHERE StockNo = 1005),
NULL)

ОБНОВЛЕНИЕ4

Если я добавлю три элемента во вложенную таблицу, останется ли оператор «FROM DUAL» как «FROM DUAL» или он изменится на что-то, отражающее три элемента? Кроме того, выражение «UNION ALL» выглядит следующим образом:

(
SELECT LineItemList_ntabtyp(
    SELECT LineItem_objtyp(1, REF(StckItem), 10, 1) FROM Stock_objtab WHERE StockNo = 1004         
    UNION ALL 
    SELECT LineItem_objtyp(2, REF(StckItem), 10, 1) FROM Stock_objtab WHERE StockNo = 1005 
    UNION ALL 
    SELECT LineItem_objtyp(3, REF(StckItem), 10, 1) FROM Stock_objtab WHERE StockNo = 1006
)
FROM DUAL
)

person user2381256    schedule 15.05.2013    source источник


Ответы (1)


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

INSERT INTO PurchaseOrder_objtab
SELECT 
    1008, 
    REF(C),
    SYSDATE, 
    '12-MAY-1999',
    (SELECT LineItemList_ntabtyp(LineItem_objtyp(1, REF(StckItem), 10, 1)) FROM Stock_objtab WHERE StockNo = 1004),
    NULL
FROM Customer_objtab C 
WHERE C.CustNo = 1;

ОБНОВЛЕНИЕ:

Я не уверен, что вы правильно выполняете задачу (я имею в виду, что хранить типы объектов в виде таблиц, на мой взгляд, бесполезно, я бы использовал управляемые обычные таблицы вместо такой архитектуры.

INSERT INTO PurchaseOrder_objtab
SELECT PurchaseOrder_objtyp(
    1008, 
    REF(C),
    SYSDATE, 
    '12-MAY-1999',
    (SELECT LineItemList_ntabtyp(LineItem_objtyp(1, REF(StckItem), 10, 1)) FROM Stock_objtab WHERE StockNo = 1004),
    NULL)
FROM Customer_objtab C 
WHERE C.CustNo = 1;

ОБНОВЛЕНИЕ 2:

Если вы хотите вставить более одного значения во вложенную таблицу, используйте перечисление (если значения записываются вручную) или подзапрос:

(
    SELECT LineItemList_ntabtyp(
        SELECT LineItem_objtyp(1, REF(StckItem), 10, 1) FROM Stock_objtab WHERE StockNo = 1004         
        UNION ALL 
        SELECT LineItem_objtyp(2, REF(StckItem), 10, 1) FROM Stock_objtab WHERE StockNo = 1005
    ) 
    FROM DUAL
)
person ZZa    schedule 15.05.2013
comment
Спасибо за ваш код. Не могли бы вы взглянуть на мое обновление OP. - person user2381256; 16.05.2013
comment
Смотрите мой обновленный пост, я НАСТОЯТЕЛЬНО рекомендую вам избавиться от всех этих объектов и использовать обычные таблицы в конце концов.. И создавать объекты из данных только на уровне интерфейса, а не в базе данных, это не его цели. - person ZZa; 16.05.2013
comment
Ваш код генерирует эту ошибку: Ошибка SQL: ORA-00904: STCKITEM: недопустимый идентификатор. Мое обновление исправляет это, но возникает эталонная ошибка. Кроме того, мне НУЖНО использовать таблицы, созданные из объектов. Это входит в мои обязанности. - person user2381256; 16.05.2013
comment
Это означает, что в Customer_objtab нет столбца StckItem, предположим, из-за того, что таблица Customer_objtab также содержит объекты, а не обычные столбцы. - person ZZa; 16.05.2013
comment
Ошибка не имеет ничего общего с таблицей Customer_obj. Посмотрите на мое обновление. Ошибка как-то связана с LineItemList_ntabtyp. - person user2381256; 16.05.2013
comment
Спасибо за ваш код. Не могли бы вы взглянуть на мое обновление о более чем одном StockItem? - person user2381256; 21.05.2013
comment
Пожалуйста, взгляните на Update4. - person user2381256; 21.05.2013
comment
Да все будет как вы написали. - person ZZa; 21.05.2013