Как исправить ORA-01401: вставленное значение слишком велико для столбца при вставке в многоуровневую вложенную таблицу

Ниже приведен запрос на создание типа таблицы/объекта. Таблицы созданы успешно

CREATE TYPE ft_obj AS OBJECT (
    ftid         NUMBER(5),
    ftlocation   VARCHAR(30),
    country      VARCHAR(10)
);
/

CREATE TABLE ft_table OF ft_obj (
    ftid PRIMARY KEY
) OBJECT IDENTIFIER IS PRIMARY KEY;
/

CREATE TYPE frod_obj AS OBJECT (
    prodid           NUMBER(6),
    ft_ref           ft_obj,
    proddesc         VARCHAR(50),
    costperitem      DECIMAL,
    labcostperitem   DECIMAL
);
/

CREATE TABLE frod_table OF frod_obj (
    prodid PRIMARY KEY
) OBJECT IDENTIFIER IS PRIMARY KEY;

CREATE TYPE wf_obj AS OBJECT (
    wfid           NUMBER,
    ft_ref         ft_obj,
    wfname         VARCHAR(30),
    taxcode        INT,
    yearlyincome   DECIMAL,
    yearlytax      DECIMAL
);
/

CREATE TABLE wf_table OF wf_obj (
    wfid PRIMARY KEY
) OBJECT IDENTIFIER IS PRIMARY KEY;
/

CREATE TYPE wfusage_obj AS OBJECT (
    jobdate         DATE,
    jobhours        INT,
    jobhourlyrate   DECIMAL,
    jobposted       CHAR,
    wfid_ref        REF wf_obj
);
/

CREATE TYPE wfusage_nesttabtyp AS
    TABLE OF wfusage_obj;
/

CREATE TABLE wfusage_objtab OF wfusage_obj;
/

CREATE TYPE odetails_obj AS OBJECT (
    mfid           NUMBER,
    prodid_ref     REF frod_obj,
    quantity       INT,
    itemprice      DECIMAL,
    wfusage_ntab   wfusage_nesttabtyp
);
/

CREATE TYPE odetails_nesttabtyp AS
    TABLE OF odetails_obj;
/

CREATE TYPE prod_obj AS OBJECT (
    prodoid          NUMBER,
    odate            DATE,
    promisedate      DATE,
    completiondate   DATE,
    shipmentdate     DATE,
    status           VARCHAR(20),
    odetails_ntab    odetails_nesttabtyp
);
/

CREATE TABLE prod_objtab OF prod_obj (
    PRIMARY KEY ( prodoid )
) OBJECT IDENTIFIER IS PRIMARY KEY
NESTED TABLE odetails_ntab STORE AS oprod_ntab ( (
    PRIMARY KEY ( nested_table_id,
                  mfid )
)
ORGANIZATION INDEX
COMPRESS 
NESTED TABLE wfusage_ntab STORE AS wforder_ntab
)
RETURN AS LOCATOR
/

ALTER TABLE oprod_ntab ADD (
    SCOPE FOR ( prodid_ref ) IS frod_table
);
/

При вставке данных во вложенную таблицу возникает ошибка ORA-01401: вставленное значение слишком велико для столбца. Ниже приведен запрос на вставку

INSERT INTO prod_objtab VALUES (
 46000,
 '25-April-2019',
 '12-May-2019',
 '13-May-2019',
  '13-May-2019',
  'COMPLETED',
  odetails_nesttabtyp(
      odetails_obj(46001
                    ,(SELECT REF(pt) 
                          FROM frod_table pt
                          WHERE pt.prodid = 10002)
                    ,100
                    ,400
                   ,wfusage_nesttabtyp(
                     wfusage_obj('25-April-2019'
                              ,60
                              ,100
                              ,'AME',
                             (SELECT REF(wf) 
                              FROM wf_table wf
                              WHERE wf.wfid = 252)
                    )
                )
              ) 
            )
          )

получаю ошибку в строке 9

ORA-01401: вставленное значение слишком велико для столбца


person user1882624    schedule 19.05.2019    source источник


Ответы (1)


Потратив более часа на отладку этого, я могу сказать, какая ужасная модель данных. Подобные вложенные объекты иллюстрируют врожденные проблемы объектно-ориентированного программирования как метода управления данными.

Во всяком случае, проблема в следующем (неизбежно последнее, на что я смотрел):

  wfusage_obj('25-April-2019'
                          ,60
                          ,100
                          ,'AME', <------------ culprit
                         (SELECT REF(wf) 
                          FROM wf_table wf
                          WHERE wf.wfid = 252)
                )

'AME' состоит из трех символов. Это заполняет wfusage_obj.jobposted, который вы определили как CHAR. Законный синтаксис, но если мы не указываем длину данных, по умолчанию используется CHAR(1). Очевидно, что это два символа вместо 'AME'. Это должно быть (как минимум) CHAR(3).

Как только вы исправите это, вы споткнетесь

ORA-22979: невозможно ВСТАВИТЬ объектный вид REF или пользовательский REF

Это связано с тем, что вы определили свои таблицы с помощью OBJECT IDENTIFIER IS PRIMARY KEY. Следовательно, вы не можете использовать REF для этих таблиц. Итак, вам нужно удалить это из определений таблиц, чтобы ваш код работал.

Я опубликовал демонстрацию на db‹>fiddle

person APC    schedule 19.05.2019