Files
roafacturare/docs/cercetare/idfact_refolosire_si_documente.md
2026-09-09 22:19:22 +03:00

20 KiB

Cercetare S9: reemiterea unui document cu acelasi ID_FACT (SET_IDFACT + DOCUMENTE)

Verdict (rezumat)

DA, dar cu conditii — nu e o schimbare izolata. SET_IDFACT activ (PACK_CONTAFIN.pck:3037-3040) ia neconditionat un ID_FACT nou din SEQ_IdFact; niciun apelant din toata suita (~25-30 copii identice ale oscrie_in_fisiere.prg, cate una per produs) ii impune un ID_FACT. Varianta comentata (:3016-3035, cauta pe NRACT+SERIE_ACT+DATAACT+ID_CTR cu STERS=0) nu rezolva S9 ca atare: dupa stergerea soft a documentului vechi, STERS e deja 1, cautarea nu-l gaseste, si cade tot pe secventa — plus riscul de coliziune cu un document viitor neinrudit care are aceleasi 4 campuri. Blocajul real nu e in SET_IDFACT, ci in scrierea din DOCUMENTE: acolo e un INSERT simplu (:796-817) pe ID_DOC, care e PRIMARY KEY (PK_DOCUMENTE, unic, fn_script.sql:5192-5198). Stergerea (STERGE_DIN_ACT:1835-1855) e soft-delete pur — ACT.STERS=1, apoi DOCUMENTE.STERS=1 pentru id_fact-urile gasite pe acel COD — randul vechi nu se sterge fizic. Deci reemiterea cu acelasi ID_FACT, cu codul de azi neschimbat, ar arunca ORA-00001 la insertul in DOCUMENTE, pentru ca randul cu acel ID_DOC inca exista (doar marcat STERS=1). Varianta MERGE deja comentata (:818-847) nu ajuta din prima: are doar WHEN NOT MATCHED, fara WHEN MATCHED, deci daca randul exista deja l-ar ignora tacit — documentul reemis ar ramane cu DOCUMENTE.STERS=1. Concluzie operationala: reutilizarea e posibila, dar cere trei schimbari simultane (detaliate la C.7), nu doar reactivarea codului comentat din SET_IDFACT.

A. SET_IDFACT

A.1 — Ramura activa vs. ramura comentata

Cod integral, PACK_CONTAFIN.pck:3014-3040:

  ------------------------------------------------------------------------------------
  /* -- 25.02.2013 : am comentat pentru ca se face unirea id_fact pe listarea din JC/JV
    PROCEDURE SET_IDFACT(tdDataAct   ACT_TEMP.DATAACT%TYPE,
                       tcSerie_Act ACT_TEMP.SERIE_ACT%TYPE,
                       tnNrAct     ACT_TEMP.NRACT%TYPE,
                       tnId_Ctr    ACT_TEMP.ID_CTR%TYPE) IS
    V_ID_FACT DOCUMENTE.ID_DOC%TYPE;
  BEGIN
    BEGIN
      SELECT ID_DOC
        into pack_contafin.nIdFact
        FROM DOCUMENTE
       WHERE NRACT = tnNrAct
         AND NVL(SERIE_ACT, '+-') = NVL(tcSerie_Act, '+-')
         AND DATAACT = tdDataAct
         AND NVL(ID_CTR, 0) = NVL(tnId_Ctr, 0)
         AND STERS = 0;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        SELECT SEQ_IdFact.NEXTVAL into pack_contafin.nIdFact FROM DUAL;
    END;
  END SET_IDFACT;*/
  ------------------------------------------------------------------------------------
  PROCEDURE SET_IDFACT(V_GCS IN VARCHAR2) IS
  BEGIN
    SELECT SEQ_IdFact.NEXTVAL into pack_contafin.nIdFact FROM DUAL;
  END SET_IDFACT;

Diferenta de comportament daca s-ar reactiva varianta comentata: in loc sa genereze mereu un ID_FACT nou, ar cauta intai in DOCUMENTE un document nesters (STERS=0) cu aceeasi combinatie NRACT + SERIE_ACT + DATAACT + ID_CTR, si doar daca nu gaseste nimic ar cere secventa. Doua probleme pentru S9:

  • nu se aplica la reemitere: documentul vechi e deja marcat STERS=1 inainte de rescriere (vezi B.6), asa ca filtrul STERS=0 nu-l gaseste — cade tot pe SEQ_IdFact.NEXTVAL, exact ca azi;
  • risc de coliziune: daca NRACT/SERIE_ACT/DATAACT/ID_CTR ar coincide intamplator cu alt document nesters (nu neaparat cel pe care il reemitem), i-ar imprumuta ID_FACT-ul aceluia. Semnatura veche are 4 parametri de identitate diferiti de semnatura activa (1 parametru V_GCS, folosit doar ca "user"/context, nefolosit in corp) — deci reactivarea ar cere fie o supraincarcare, fie schimbarea semnaturii peste tot unde e chemata (vezi A.2).

A.2 — Apelanti

Un singur punct de apel in PL/SQL: PACK_CONTAFIN.pck:721, in bucla din SCRIE_IN_ACT:

      pack_contafin.set_idfact(V_GCS);
      /* 25.02.2013 : se face cumularea id_fact pe listarea din RC/RJ
      PACK_CONTAFIN.SET_IDFACT(itemfact.dataact, itemfact.serie_act, itemfact.nract, itemfact.id_ctr);*/
      lnIdFact := get_idFact();

buclat pe grupuri distincte (NRACT, DATAACT, DATAIREG, SERIE_ACT, ID_CTR, ID_SET) extrase din ACT_TEMP WHERE ID_FACT = -1 (:713) — deci -1 e sentinela "acest rand cere un ID_FACT nou".

SCRIE_IN_ACT insusi e apelat doar pe drumul de scriere, niciodata pe cel de stergere — in finalizeaza_scriere_act_rul (:8449-8459):

    if tnScrieSterge <> 2 then
      pack_contafin.SCRIE_IN_ACT(user);
      ...
    else
      pack_contafin.STERGE_DIN_ACT(user, lnAn, lnLuna, tnCod, tnIdUtil, tnModificareNota);
      ...

Deci SET_IDFACT nu se atinge deloc la stergere — confirma ca azi cele doua operatii (stergere + reemitere) sunt independente unele de altele in privinta ID_FACT.

Cine cheama final_scriere_act_rul_local / SCRIE_IN_ACT din VFP: acelasi fisier COMUN\programe\oscrie_in_fisiere.prg, replicat identic in ~25-30 produse ROA (verificat prin grep pe *.prg in tot D:\ROA): ROAFACTURARE, ROACONT (output), ROAGEST, ROAIMOB, ROAEFACTURA, ROADEVIZE, ROAVIN, ROACASA, ROASAL, ROAPRETURI, ROAOBINV, ROARESTAURANT, ROACOMENZI, ROAAPROV, ROASITOP, ROASITFIN, ROADECL, ROASALSPEC, ROABAVERT, ROACONIMPORT, ROAPRINT, s.a. — plus doua variante care apeleaza SCRIE_IN_ACT direct, fara wrapper-ul local: CONTAFIN2ORA\VFP2ORA\Programe\oscrie_in_fisiere.prg:367, ROADEFSALARII\COMUN\programe\oscrie_in_fisiere.prg:141, ROARESTAURANTCONFIG\COMUN_ROA\programe\oscrie_in_fisiere.prg:135. Un al doilea import vechi (COMUN\datemenu\xold\import_xdbf\oscrie_in_fisiere.prg) apare in multe produse dar e comentat integral (*!*) — inactiv.

Niciun apelant nu impune un ID_FACT. Toti trimit ID_FACT = -1 in ACT_TEMP (via sql_temp_insert in oscrie_in_fisiere.prg:126-137, care copiaza direct campurile din cursorul VFP, inclusiv id_fact) si lasa SCRIE_IN_ACT sa-l completeze din secventa. Confirmare suplimentara in COMUN\clase\omodificari.vc2:4131-4132: "daca se schimba partenerul, se pune id_fact = -1 in loc de 0 pentru a se putea genera un nou id_fact" — exact sentinela pe care se bazeaza bucla din SCRIE_IN_ACT.

A.3 — Variabila/parametru existent pentru un ID_FACT dorit

Nu exista azi. PACK_CONTAFIN are o variabila de pachet nIdFact (setata de SET_IDFACT, citita de GET_IDFACT), dar e scrisa neconditionat de fiecare apel al lui SET_IDFACT — nu poate fi folosita ca "intrare" fara sa se schimbe corpul procedurii. Nu exista niciun nid_... global, nici alt parametru de sesiune care sa transmita un ID_FACT dorit lui SET_IDFACT sau lui SCRIE_IN_ACT. Ar trebui adaugata o variabila noua de pachet (ex. un "ID_FACT fortat", implicit NULL), citita doar in corpul activ al lui SET_IDFACT, consumata si resetata la prima folosire — vezi C.8. Acelasi diagnostic e deja notat in planul de proiect, plan_13_unificare_formular_facturare.md:1717-1719: "ID_FACT. Se citeste inainte de stergere ... si se impune documentului nou, printr-un comutator folosit numai de regenerare. SET_IDFACT nu se schimba neconditionat — e cod comun intregii suite."

B. DOCUMENTE la reemitere cu acelasi ID_FACT

B.4 — INSERT sau UPDATE/MERGE azi

PACK_CONTAFIN.pck:788-817, in interiorul buclei din SCRIE_IN_ACT, cod activ (INSERT simplu):

      -- SCRIE IN DOCUMENTE
      lnTvaIncasare := case when itemfact.tva_incasare > 0 then 1 else 0 end;
      -- 25.02.2013 : am repus insertul pentru ca se face cumularea id_fact pe listarea din RC/RJ
      INSERT INTO DOCUMENTE
        (ID_DOC, ID_UTIL, DATAORA, TVA_INCASARE, SERIE_ACT, NRACT, DATAACT, DATAIREG, ID_CTR, ID_SET)
      VALUES
        (lnIdFact, lnID_Util, LD_DATAORA, lnTvaIncasare, itemfact.serie_act, itemfact.nract,
         itemfact.dataact, itemfact.dataireg, decode(itemfact.id_ctr, 0, NULL, itemfact.id_ctr),
         itemfact.id_set);
      /*
      -- modificare ROACONT v 2.4.0 (27.12.2012): am adaugat serie_act, nract, dataact
      -- modificare 21.02.2013: am adaugat id_ctr
      MERGE INTO DOCUMENTE A
      USING (SELECT lnIdFact as ID_DOC, itemfact.serie_act as SERIE_ACT, itemfact.nract as NRACT,
                    itemfact.dataact as DATAACT,
                    decode(itemfact.id_ctr, 0, NULL, itemfact.id_ctr) AS ID_CTR
               FROM DUAL) B
      ON (A.ID_DOC = B.ID_DOC)
      WHEN NOT MATCHED THEN
        INSERT (ID_DOC, ID_UTIL, DATAORA, TVA_INCASARE, SERIE_ACT, NRACT, DATAACT, ID_CTR)
        VALUES (B.ID_DOC, lnID_Util, LD_DATAORA, lnTvaIncasare, B.SERIE_ACT, B.NRACT, B.DATAACT, B.ID_CTR);*/

Deci azi e mereu un INSERT nou — pe drumul normal (ID_FACT vine din secventa, mereu inexistent in DOCUMENTE) asta e corect, dar pentru cazul S9 (ID_FACT reutilizat, deja existent — chiar si soft-sters) INSERT-ul ar da eroare de unicitate (vezi B.5). Varianta MERGE comentata are doar WHEN NOT MATCHED — daca s-ar reactiva neschimbata, un ID_DOC deja existent ar fi pur si simplu ignorat (fara WHEN MATCHED), documentul reemis ramanand cu randul vechi din DOCUMENTE (cu TVA_INCASARE/ID_SET nemodificate si, mai grav, cu STERS neresetat — vezi B.6).

B.5 — Constrangere de unicitate pe DOCUMENTE

DDL gasit in D:\ROA\DATABASE\ALTELE\Creare_server_scripturi\FirmaNoua\fn_script.sql:5162-5198:

CREATE TABLE "DOCUMENTE" ("ID_DOC" NUMBER(20, 0) NOT NULL ENABLE, "DATAORA" DATE NOT NULL ENABLE,
  "ID_UTIL" NUMBER(5, 0) NOT NULL ENABLE, "STERS" NUMBER(1, 0) NOT NULL ENABLE,
  "DATAORAS" DATE, "ID_UTILS" NUMBER(5, 0) NOT NULL ENABLE) ...
...
CREATE UNIQUE INDEX "PK_DOCUMENTE" ON "DOCUMENTE" ("ID_DOC") ...
ALTER TABLE "DOCUMENTE" ADD CONSTRAINT "PK_DOCUMENTE" PRIMARY KEY ("ID_DOC") USING INDEX ... ENABLE

Da: ID_DOC e PRIMARY KEY, unic. (Coloanele SERIE_ACT/NRACT/DATAACT/DATAIREG/ID_CTR/ID_SET/ TVA_INCASARE din INSERT-ul de la B.4 nu apar in acest script — script vechi de firma noua, probabil tabela a fost alterata ulterior cu ALTER TABLE ADD COLUMN; constrangerea de PK insa e stabila si nu are motiv sa fi fost scoasa.) Un INSERT INTO DOCUMENTE (ID_DOC=...) cu o valoare de ID_DOC care exista deja (chiar si STERS=1) arunca ORA-00001: unique constraint (PK_DOCUMENTE) violated. Nu am gasit alta constrangere de unicitate pe DOCUMENTE; nici FK de la ACT.ID_FACT catre DOCUMENTE.ID_DOC (ACT.ID_FACT e doar indexat, IDX_ID_FACT, fn_script.sql:1637, fara constrangere de integritate referentiala gasita) — deci reinserarea de randuri in ACT cu ID_FACT reutilizat nu e blocata de vreo constrangere pe ACT insusi; blocajul e exclusiv pe DOCUMENTE.

B.6 — Randurile vechi la stergere: fizic sterse, STERS=1, sau raman

Soft-delete pur, pe toate cele patru tabele relevante — nimic nu se sterge fizic.

STERGE_DIN_ACT (PACK_CONTAFIN.pck:1815-1859), apelata din finalizeaza_scriere_act_rul cand tnScrieSterge = 2:

  PROCEDURE STERGE_DIN_ACT(V_GCS VARCHAR2, tnAn in number, tnLuna in number, tnCod in number,
                           tnId_utils in number, tnTip IN NUMBER) is
    -- tnTip : 0 = modificare ; 1 = stergere
    ...
  BEGIN
    ...
    UPDATE /*+ index(ACT IDX_COD) */ ACT
       SET STERS = 1, DATAORAS = LD_DATAORA, ID_UTILS = lnId_util
     WHERE COD = tnCod and an = tnAn and luna = tnLuna;

    IF lnTip = 1 THEN
      UPDATE DOCUMENTE
         SET STERS = 1, ID_UTILS = LNID_UTIL, DATAORAS = LD_DATAORA
       WHERE ID_DOC IN
             (SELECT /*+ index(ACT IDX_COD) */ DISTINCT ID_FACT
                FROM ACT
               WHERE COD = tnCod and an = tnAn and luna = tnLuna
                 AND ID_FACT <> 0
                 and ID_SET not in (90501, 90021)
                 AND NOT (SCD = '4426' AND SCC = '4428')
                 AND NOT (SCD = '4428' AND SCC = '4427'));
    END IF;

    update act_temp set suma = -suma, suma_val = -suma_val;
  END STERGE_DIN_ACT;

ACT -> STERS=1 (randurile raman fizic, pe acelasi COD). Cand tnTip=1 (stergere, nu simpla modificare), DOCUMENTE primeste si el STERS=1, pentru toate ID_FACT distincte gasite pe acel COD in ACT (cu exceptiile de mai sus pentru seturi/conturi speciale). Nicaieri nu am gasit un UPDATE DOCUMENTE ... SET STERS = 0 — cautare exhaustiva in PACK_CONTAFIN.pck (grep -i "UPDATE DOCUMENTE") a dat un singur rezultat, cel de mai sus. Deci nu exista azi niciun mecanism care sa "reinvie" un rand din DOCUMENTE.

La fel, STERGE_DIN_RUL / STERGE_DIN_RUL_OBINV (:1861-1893) fac UPDATE ... SET STERS = 1 pe RUL/RUL_OBINV, fara stergere fizica.

Pentru IREG_PARTENERI si JV2007 situatia e diferita in mod util pentru S9: acestea nu sunt copii 1:1 ale documentului, ci agregate recalculate prin MERGE pe chei de business (an, luna, cont / ID_FDOC, ID_FACT, NRACT, SERIE_ACT, DATAACT, DATAIREG, ID_PART, ...) — vezi SCRIE_JV_2007 (:3328-3373+) si SCRIE_IN_IREG_PARTENERI/EXECUTA_SCRIE_IN_IREG (:7030+, :7607+). Ambele sunt apelate si pe drumul de scriere, si pe cel de stergere (finalizeaza_scriere_act_rul:8495-8578, fara conditie pe tnScrieSterge in afara sursei: act_temp la scriere/stergere, act la refacere). La stergere, sterge_document (:7699-8118) reinsereaza in ACT_TEMP copii ale randurilor vechi din ACT/RUL/RUL_OBINV, cu acelasi ID_FACT ca inainte (coloana id_fact e copiata direct din sursa, nu resetata la -1), asa ca MERGE-ul din SCRIE_JV_2007/SCRIE_IN_IREG_PARTENERI recalculeaza (compenseaza) exact randul cu acel ID_FACT — nu creeaza duplicate. Deci reutilizarea ID_FACT-ului nu produce dubluri in JV2007/ IREG_PARTENERI; problema e strict izolata la DOCUMENTE.

Nota din plan, care confirma independent aceasta zona de risc: plan_13_unificare_formular_facturare.md:1737: "De verificat si daca DOCUMENTE primeste un al doilea rand pe acelasi ID_DOC sau il refoloseste." — raspunsul, dupa aceasta cercetare: niciuna din cele doua, in starea actuala a codului — ar arunca eroare de unicitate, nu ar produce liniste tacuta cu duplicat sau refolosire.

C. Verdictul care conteaza

C.7 — Se poate reemite cu acelasi ID_FACT fara sa se strice nimic?

DA, dar cu conditii — niciuna dintre ele nu e implementata azi:

  1. Nu folosi varianta comentata a lui SET_IDFACT ca atare. Cautarea STERS=0 nu gaseste documentul (deja sters soft inainte de rescriere) si e vulnerabila la coliziuni pe chei de business partajate cu alt document. In loc de cautare, ID_FACT-ul trebuie citit explicit inainte de stergere (VFP il are deja in cursorul documentului editat) si transmis pe drumul de scriere — exact ce zice planul S9.
  2. SET_IDFACT are nevoie de o cale de intrare noua, inerta implicit. O variabila de pachet noua (ex. "ID_FACT fortat", NULL default) + o procedura noua de setat-o explicit inainte de scriere; corpul activ al SET_IDFACT verifica intai variabila, o consuma si o reseteaza; daca e NULL (cazul general — toate celelalte ~25-30 apeluri din suita), comportamentul e identic cu azi (secventa). Nu se toarna in semnatura existenta SET_IDFACT(V_GCS), ca sa nu se schimbe apelul de la niciun alt caller.
  3. Scrierea in DOCUMENTE trebuie sa devina un upsert real, cu WHEN MATCHED. Nici INSERT-ul activ, nici MERGE-ul comentat (fara WHEN MATCHED) nu revigoreaza un rand soft-sters. E nevoie de un MERGE ... WHEN MATCHED THEN UPDATE SET STERS = 0, DATAORA = ..., ID_UTIL = ..., TVA_INCASARE = ..., SERIE_ACT = ..., NRACT = ..., DATAACT = ..., DATAIREG = ..., ID_CTR = ..., ID_SET = ... pe langa WHEN NOT MATCHED THEN INSERT (cazul normal, ID_FACT nou din secventa).
  4. Succesiunea corecta, in aceeasi tranzactie (deja planificata in S9 la nivel de VFP — vezi plan_13...md:1713-1719, mutarea stergerii in tranzactia deschisa de scriere): sterge documentul vechi (soft-delete, ca azi) -> seteaza variabila de la punctul 2 cu ID_FACT-ul citit inainte de stergere -> scrie documentul nou prin drumul obisnuit (ACT_TEMP cu ID_FACT = -1 ca de obicei, dar acum grupul respectiv va primi ID_FACT-ul fortat in loc de unul nou) -> commit doar dupa ce ambele operatii au avut succes; orice eroare -> rollback total, documentul vechi ramane intact.
  • NU (fara aceste conditii): INSERT INTO DOCUMENTE cu ID_DOC reutilizat, cat timp randul vechi e inca prezent cu STERS=1, arunca ORA-00001 pe PK_DOCUMENTE — asta e dovada, nu presupunere (B.5 + B.4).

C.8 — Suprafata de risc pentru restul suitei

  • ~25-30 cai de apel trebuie sa ramana neafectate: toate copiile COMUN\programe\ oscrie_in_fisiere.prg din fiecare produs ROA (listate in A.2), plus cele 3 variante care apeleaza SCRIE_IN_ACT direct. Toate trec prin acelasi punct final: SET_IDFACT(V_GCS) in PACK_CONTAFIN.pck:3037.
  • Garantia structurala propusa: variabila de pachet noua, default NULL/inert, citita doar in interiorul corpului activ al lui SET_IDFACT (nu in semnatura, nu in vreun parametru propagat de apelanti); se seteaza explicit doar de codul de regenerare din ROAFACTURARE, chiar inainte de a incepe scrierea documentului reemis, si se consuma/reseteaza la prima citire (fie in SET_IDFACT, fie la finalul tranzactiei, ca sa nu "scurgi" valoarea catre urmatoarea scriere neinrudita din aceeasi sesiune Oracle — relevant daca goExecutor/conexiunea e reutilizata intre operatii ale aceluiasi utilizator in acelasi produs). Cu default inert si citire localizata strict in corpul lui SET_IDFACT, toate celelalte ~25-30 cai raman byte-for-byte identice cu azi — nu e nevoie sa se verifice fiecare apelant individual, garantia e la sursa (variabila neinitializata = comportament vechi).
  • Riscul real nu e in SET_IDFACT, ci in DOCUMENTE. Schimbarea INSERT->MERGE cu WHEN MATCHED la PACK_CONTAFIN.pck:796-817 e riscanta pentru toata suita in alt sens: WHEN MATCHED s-ar declansa doar cand ID_DOC (generat din secventa) coincide cu unul existent — ceea ce, pe drumul normal, nu se intampla niciodata (secventa e monoton crescatoare, nu se repeta), deci practic ramura noua e inerta pentru toti apelantii actuali si activa doar cand variabila de la C.8 a fost setata explicit. Totusi orice modificare la acest INSERT/MERGE e in cod comun apelat de toata suita si trebuie testata pe cel putin un ciclu normal de scriere (fara variabila fortata) in fiecare produs care scrie facturi/note, nu doar in ROAFACTURARE.

Ramas de verificat pe baza vie

  • Structura curenta reala a tabelei DOCUMENTE (DDL-ul citat e dintr-un script vechi de "firma noua"; coloanele SERIE_ACT/NRACT/DATAACT/DATAIREG/ID_CTR/ID_SET/TVA_INCASARE folosite de INSERT-ul activ nu apar in acel DDL — probabil adaugate ulterior prin ALTER TABLE). De rulat pe baza vie: SELECT column_name, nullable FROM user_tab_columns WHERE table_name = 'DOCUMENTE' ORDER BY column_id; si SELECT constraint_name, constraint_type FROM user_constraints WHERE table_name = 'DOCUMENTE'; — sa se confirme ca PK_DOCUMENTE e inca activa si ca nu exista alta constrangere aparuta intre timp.
  • Daca exista deja documente reale in productie unde DOCUMENTE.ID_DOC a fost, intr-un fel sau altul, reutilizat (ex. printr-o interventie manuala) — de verificat cu SELECT id_doc, count(*) FROM documente GROUP BY id_doc HAVING count(*) > 1; (ar trebui sa fie gol, dat fiind PK-ul, dar merita confirmat inaintea oricarei schimbari).
  • Comportamentul exact al finalizeaza_stergere_nota/finalizeaza_modificare_nota (:8601+, nu au fost citate integral aici) fata de ID_FACT/ID_FACTD — relevante daca reemiterea schimba seria/numarul, nu doar continutul (cazul S9 "de baza" e cel mai simplu: acelasi NRACT/SERIE_ACT).
  • Comportamentul lui EXECUTA_SCRIE_TVA/SCRIE_JC_2007 (mentionate la :8504-8540, cazul an < 2007 sau JC) fata de reutilizarea ID_FACT — nu au fost verificate in detaliu, doar SCRIE_JV_2007.
  • Nu am putut testa efectiv (fara acces la baza vie) daca ORA-00001 e chiar eroarea ridicata de Oracle in acest scenariu exact — e o deductie directa din DDL (PK unic + INSERT simplu pe coloana respectiva), dar merita o rulare de proba pe o baza de test inainte de a proiecta solutia finala.