- leaga_skills.ps1: expune skill-urile in ~/.claude/skills prin symlink (citit si de Claude Code, si de opencode), fara copiere - rutare zona->skill in reguli_lucru pct. 7, README, AGENTS.md; skill-ul devine proprietarul procedurii, docurile raman referinta conditionata - rec_skills.md: decizia, inventarul si cum se adauga un skill nou
4.2 KiB
Randuri pierdute tacit intre VFP si Oracle (SQLEXEC + NO_DATA_FOUND)
O eroare reala in Oracle devine succes raportat in VFP. Mecanismul care ascunde defectul ramane activ pana cand e inchis explicit, iar orice reparatie ulterioara ramane neverificabila.
Cand se foloseste
- Un apel VFP catre o procedura PL/SQL intoarce mai putine randuri sau zero, fara eroare.
- Triggeri textuali: "SQLEXEC nu intoarce nimic", "lipsesc randuri", "procedura intoarce gol dar fara eroare", "documentul are mai putine linii decat pe ecran", "SELECT INTO".
- Scrii sau modifici o procedura care contine
SELECT ... INTOsi e apelata din VFP. SQLExec()intoarce 1 (succes), dar cursorul rezultat e gol sau incomplet.
Regula
-
Garda intai, cauza dupa. Infasoara FIECARE
SELECT ... INTOinBEGIN ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20000, '...'). Codul de eroare (FACT-0xx) se cauta liber inUSER_SOURCEinainte de a-l folosi. -
Daca absenta randului e legitima, nu o lasa sa cada: foloseste un agregat (
SELECT COUNT(*)/MAX(...) INTO) sau un cursor care intoarce garantat un rand. -
Simetrizeaza predicatul pe coloana SI pe parametru - sirul gol din VFP este NULL in Oracle:
-- gresit: 'XXXX' = NULL da UNKNOWN, deci zero randuri AND NVL(A.CONT, 'XXXX') = V_CONT -- corect: AND NVL(A.CONT, 'XXXX') = NVL(V_CONT, 'XXXX') -
Partea VFP e obligatorie.
SQLExec()nu e sursa de adevar. Testeaza numarul de randuri:lnRez = SQLEXEC(lnH, "begin PACK_FACTURARE.adauga_articol_factura(...); end;", "curRez") IF lnRez < 0 OR RECCOUNT("curRez") = 0 * trateaza ca esec, nu ca succes ENDIF
Nu raporta "functioneaza" pe baza lui lnSucces.
Capcane
SQLExec()intoarce 1 laSQL_NO_DATA-If lnSucces < 0nu prinde nimic, linia dispare fara urma. Verificarea de succes trebuie sa includa si numarul de randuri.- Sirul gol este NULL in Oracle:
'XXXX' = NULLda UNKNOWN, deci predicatul cade pe zero randuri. Santinela doar pe coloana nu e suficienta. - Camp lipsa din lista de insert a cursorului, pe o coloana numerica fara
NULL: ramane0tacit, nu NULL si nu eroare, iar predicatul cade pe0- acelasi simptom, alta cauza. - Fara asertiune pe numarul de linii, toate testele existente trec: identitatea documentului si legaturile lui se pastreaza corect, doar liniile lipsesc.
- Nu presupune ca un cod
FACT-0xxe liber - verifica-l inUSER_SOURCE.
Criterii de acceptare si dovada
Fara dovada da/nu de mai jos, defectul NU se raporteaza ca reparat.
- Numaratoarea de randuri e asertata intr-un test headless pe fluxul real: acelasi document,
acelasi input,
RECCOUNT()/SELECT COUNT(*)egal cu numarul de linii din sursa. Un total mai mic nu e acceptabil, chiar daca nu exista eroare. - Handler-ul exista pe disc, nu doar in intentie - interogare pe
USER_SOURCEcare arataEXCEPTION WHEN NO_DATA_FOUNDin ramura procedurii vizate. - Test negativ: forteaza un predicat care nu potriveste nimic si confirma ca primesti eroare
-20000in VFP, nu succes cu cursor gol. - "Arata bine" / "nu a dat eroare" nu e dovada. Dovada e numarul de randuri.
Referinta (doar la nevoie)
COMUN\docs\capcana_sqlexec_no_data_found.md- mecanismul complet, precedentulPACK_FACTURARE.adauga_articol_facturasi modul de cautare preventiva inUSER_SOURCE.