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

51 lines
2.2 KiB
Markdown

# 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`.