Files
comun/docs/capcana_sqlexec_no_data_found.md
Marius Mutu 8e022d332e #13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2.

Clase: ofacturare (nucleul formularului unificat), ofacturare_comun,
ferestre_cere_date, ocomenzi, caut_ora (lista de preturi in combo-urile de
cautare), omodificari.

Programe: ofacturare impartit - ofacturare_antet, ofacturare_rutare_scriere si
ogrid_latimi sunt fisiere noi; oproceduri_facturare primeste discountul pe linie
si cota standard de TVA cand articolul nu are cota pe politica.

Documentatie: capcana SQLExec no_data_found, conventia de encoding, depanarea
testelor VFP si regulile de lucru - conflictele cu modificarile venite din alte
proiecte sunt rezolvate pastrand ambele parti.

Loguri de rulare a testelor scoase din versionare; testele raman.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
2026-09-09 21:38:25 +03:00

2.2 KiB

Capcana: linii pierdute tacut intre VFP si Oracle

Simptomul

Un document se salveaza cu mai putine linii decat are pe ecran. Fara mesaj, fara eroare, fara nimic in log. Totalurile ies mai mici, dar consistente intre ele - deci nu arata a defect.

Mecanismul, in doi pasi

  1. Un SELECT ... INTO fara handler intr-o procedura PL/SQL arunca ORA-01403 (NO_DATA_FOUND) cand predicatul nu potriveste niciun rand.
  2. ODBC il traduce ca SQL_NO_DATA, si SQLExec() intoarce 1, adica succes. Bucla din VFP testeaza If lnSucces < 0 si nu vede nimic. Linia dispare fara urma.

Deci: eroare reala in Oracle -> succes raportat in VFP.

De ce nu potriveste predicatul (cauza uzuala)

Santinela pusa doar pe coloana, nu si pe parametru:

AND NVL(A.CONT, 'XXXX') = V_CONT

VFP trimite sir gol pentru campul necompletat, iar in Oracle sirul gol este NULL; 'XXXX' = NULL da UNKNOWN, deci zero randuri. Corect e pe amandoua:

AND NVL(A.CONT, 'XXXX') = NVL(V_CONT, 'XXXX')

Pe ID_GESTIUNE acelasi tipar merge, fiindca acolo VFP chiar trimite santinela -1000.

Cauza inrudita, acelasi simptom: un camp lipsa din lista de insert a cursorului, pe o coloana numerica fara NULL - ramane 0 tacit, nu NULL si nu eroare, si predicatul cade pe 0.

Ce se face, in ordinea asta

  1. Intai garda, apoi cauza. Infasoara SELECT ... INTO in BEGIN ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20000, '... (FACT-0xx : ' || <cheia> || ')'). Fara ea, orice reparatie de cauza ramane neverificabila: mecanismul care ascunde defectul e inca acolo. Codul FACT-0xx se cauta liber in USER_SOURCE, nu se presupune ca e liber.
  2. Abia apoi simetrizeaza predicatul.
  3. Asertiune pe NUMARUL DE LINII in testul de flux. Exact piesa care lipsea: identitatea documentului si legaturile lui se pastrau corect, deci toate asertiunile existente treceau.

Cum se cauta preventiv

In USER_SOURCE: fiecare SELECT ... INTO fara EXCEPTION in ramura lui, si fiecare predicat de forma NVL(<coloana>, <santinela>) = <parametru>.

Precedent: PACK_FACTURARE.adauga_articol_factura, ramura ntip = 4 (facturare din avize) - un document reemis cu 2 linii din 4, nedetectat de doua sweep-uri la rand. Reparat 04.09.2026 cu FACT-030.