Обновить атрибут элемента во вложенной таблице - PullRequest
1 голос
/ 15 января 2010

Я создал этот тип: создать или заменить тип PRODTABLE как таблицу PROD_OBJ;

и я использую этот PRODTABLE в следующем коде PLSQL:

    FUNCTION  INSERT_PRODUCTS (

      a_supplier_id IN FORNECEDOR.ID_FORNECEDOR%TYPE,

      a_prodArray IN PRODTABLE

      ) 

     RETURN NUMBER IS

        v_error_code    NUMBER;
        v_error_message VARCHAR2(255);
        v_result        NUMBER:= 0;
        v_prod_id       PRODUTO.ID_PROD%TYPE;
        v_supplier      FORNECEDOR%ROWTYPE;
        v_prodInserted  PROD_OBJ;
        type nestedTable is table of PROD_OBJ;
        newList   nestedTable := nestedTable();

     BEGIN

     SELECT  FORNEC_OBJ(ID_FORNECEDOR,NOME_FORNECEDOR,MORADA,ARMAZEM,EMAIL,TLF,TLM,FAX) into v_supplier from fornecedor where id_fornecedor = a_supplier_id;

      FOR i IN a_prodArray.FIRST .. a_prodArray.LAST LOOP

          INSERT INTO PRODUTO (PRODUTO.ID_PROD,PRODUTO.NOME_PROD,PRODUTO.PREC_COMPRA_PROD,PRODUTO.IVA_PROD,PRODUTO.PREC_VENDA_PROD,PRODUTO.QTD_STOCK_PROD,PRODUTO.QTD_STOCK_MIN_PROD) 
          VALUES (S_PRODUTO.nextval,a_prodArray(i).NOME_PROD,a_prodArray(i).PREC_COMPRA_PROD,a_prodArray(i).IVA_PROD,NULL,NULL,NULL);

          SELECT ID_PROD into v_prod_id from PRODUTO where NOME_PROD = a_prodArray(i).NOME_PROD;

          INSERT INTO PROD_FORNECIDO VALUES (a_supplier_id, v_prod_id,a_prodArray(i).PREC_COMPRA_PROD);

          SELECT PROD_OBJ(ID_PROD,NOME_PROD,PREC_COMPRA_PROD,PREC_VENDA_PROD,QTD_STOCK_PROD,QTD_STOCK_MIN_PROD,IVA_PROD) into v_prodInserted from PRODUTO where ID_PROD= v_prod_id;
          newList.extend;
          newList(newList.last):= v_prodinserted;

        END LOOP;

        /*the next line generates Error(43,63): PLS-00642: local collection types not      allowed in SQL statements,
Error(43,63): PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got CHAR */
        INSERT INTO FORNECPRODS2 VALUES (a_supplier_id,v_supplier,newList);
        v_result:= 1; 
        RETURN v_result;
        COMMIT;
    (...)
    END;

Я хочу сделать что-то вроде a_prodArray(i):= v_prodInserted, но не могу, потому что это вложенная таблица, поэтому мне нужно найти другую, чтобы использовать ее во вставке, ИЛИ обновить каждый элемент вложенной таблицы с новым вставленным продуктом. Я должен сделать это, потому что каждый prod_obj в PRODTABLE поставляется с идентификатором = 0 из JAVA. Может быть, есть другой способ, например, сделать значение по умолчанию для первичного ключа равным SEQUENCE.nextval, я не знаю. Может ли кто-нибудь, пожалуйста, просветить меня?

Спасибо!

1 Ответ

1 голос
/ 15 января 2010

вы не сможете изменить a_prodArray, так как он объявлен как параметр IN (и поэтому не может использоваться в качестве цели назначения). Если вы объявите параметр как IN OUT, присваивание выполнится успешно:

SQL> CREATE TYPE PROD_OBJ AS OBJECT
  2  (
  3     ID_PROD   NUMBER,
  4     NOME_PROD VARCHAR2(1)
  5  )
  6  ;
  7  /     
Type created

SQL> CREATE TYPE PRODTABLE as table of PROD_OBJ;
  2  /     
Type created

SQL> CREATE FUNCTION INSERT_PRODUCTS(a_prodArray IN OUT PRODTABLE)
  2     RETURN NUMBER IS
  3  BEGIN
  4     a_prodArray(1) := prod_obj(1, NULL);
  5     RETURN 0;
  6  END;
  7  /     
Function created

SQL> DECLARE
  2     l_prod_table prodtable := prodtable();
  3     dummy NUMBER;
  4  BEGIN
  5     l_prod_table.extend();
  6     dummy := INSERT_PRODUCTS(l_prod_table);
  7  END;
  8  /     
PL/SQL procedure successfully completed

Теперь для ошибки PLS-00642 вы должны использовать EXACT тот же тип данных, что и в определении таблицы. В этом случае я предполагаю, что типом является PRODTABLE тип SQL, и вам придется объявить newList как PRODTABLE (а не тип PLSQL nestedTable).

...