11 KiB
Scripturi migrare baza de date Oracle
Scripturile de migrare a schemei (si modelele pentru scripturi noi) sunt in
DATABASE\SCRIPTURI_CLAR de sub radacina suitei ROA (gcDirMare/dirgen — ex.
D:\ROA\DATABASE\SCRIPTURI_CLAR). Sursa SVN: http://svnroa:3001/svn/ROA/DATABASE/Branches/RB-1.00.
Pentru un script nou, urmeaza formatul/conventiile celor recente de acolo. Publicarea catre clienti
(import in UPD_DATABASE + arhiva lunara): publicare-scripturi-db.md.
Reguli confirmate de Marius (24.07.2026):
- Line-endings CRLF obligatoriu in scripturile
.sql— tool-urile agentului scriu implicit LF; dupa orice scriere, verifica si converteste byte-safe LF -> CRLF (fara decodare/reincodare). Parsarea pe fluxul ROA (ex.ALINESpeCHR(13)+CHR(10)) esueaza silentios pe LF: tot fisierul devine un singur rand. versiune_db.txt(marker-ulYYYY_MM_DD_NNdin radacina aplicatiei) se scrie fara newline la final (conventia existenta).- Aplicarea prin ODBC/
goExecutor: sintaxa SQL*Plusexec pachet.procedura(...)nu functioneaza — folosestebegin pachet.procedura(...); end;. - Niciun
;la capat de linie intr-un comentariu--din interiorul unei instructiuni. SQL*Plus termina instructiunea acolo, chiar daca;-ul e in comentariu: restulCREATE VIEW-ului ajunge sa fie interpretat linie cu linie ca si comenzi, cu zeci deSP2-0734si unORA-00936derutant care arata spre comentariu. Pus la sfarsit de fraza,.in loc de;. Comentariile de dinaintea instructiunii nu sunt afectate. - Fiecare script se incheie cu
exec pack_migrare.UpdateVersiune('<nume_script>');urmat decommit;. Numele se da fara extensia.sql— o adaugaUpdateVersiune; trecuta si in argument, ajunge inVERSIUNEca..._.sql.sqlsi scriptul apare ca neaplicat la comparatia de mai jos. Toate scriptele dinSCRIPTURI_CLARo omit, iar inVERSIUNEnu exista niciun rand cu dubla extensie. DDL-ul comite implicit, darUpdateVersiunee DML: faracommitexplicit, un script se poate aplica fara ca versiunea sa se inregistreze, iarVERSIUNEajunge sa minta despre ce s-a aplicat. - Rularea manuala se face conectat pe schema tinta (
CONTAFIN_ORACLEpentruco_, schema firmei pentruff_), niciodata cu un user de lucru. DDL-ul neprefixat (create or replace package ...) merge pe schema conexiunii: pe alt user iesePLS-00304si ramane un obiect orfan, iar pachetul tinta ramane neschimbat. In acelasi script, DML-ul pe tabele cu sinonim public nimereste tabela reala si pare ca totul a mers — verifica intotdeauna iesirea sqlplus siall_objects.PACK_UPDATEfaceCONNECT <schema>/<parola>@ROAreal per schema (UpdateSchemaSQLPLUS, parola dinSERVER_INFO), deci scriptul neprefixat e corect pentru livrare.
Sursa de referinta pentru DDL: MARIUSM_AUTO, nu productia
Regula lui Marius (06.08.2026): orice modificare de tabela, view, procedura, functie sau pachet se
scrie plecand de la sursa din schema de dezvoltare MARIUSM_AUTO (ROA_CENTRAL), niciodata de la
sursa citita dintr-o schema de client (VENDING, ACN, ...). Schemele de client raman in urma:
pot avea scripturi neaplicate sau variante livrate separat (ex. pachetele _10G_ROMCONSTRUCT), iar o
modificare scrisa peste o sursa veche sterge corectii deja livrate.
Schemele de client raman utile doar pentru masuratori pe date reale, in citire.
Verifica intai ca MARIUSM_AUTO e la zi
"Ultima versiune din dev" e ultima versiune doar daca toate scripturile din SCRIPTURI_CLAR chiar au
fost aplicate acolo. pack_migrare.UpdateVersiune inregistreaza fiecare script aplicat in tabela
VERSIUNE (script_final = numele fisierului, cu tot cu .sql), deci diferenta se vede direct:
select script_final, data_final from versiune order by data_script desc, seq_script desc;
Get-ChildItem D:\ROA\DATABASE\SCRIPTURI_CLAR -Recurse -Filter *.sql |
Select-Object -ExpandProperty Name | Sort-Object
Daca lipsesc scripturi din VERSIUNE, nu porni modificarea pe sursa de acolo — semnaleaza-i lui
Marius ce nu e aplicat. Exportul sursei de referinta: oracle_export.md.
Continutul unui script
- Minimul necesar si intotdeauna SCOPED:
update/insertdoar pe randurile cazului tratat (setul, codul, firma anume), niciodata pe toate randurile care "seamana" cu el. - Fara
selectde raportare in script — nu-l citeste nimeni la aplicare si poate da eroare. Verificarile se fac inainte, separat, pe schema de lucru. - Idempotent: rulat de doua ori nu mai schimba nimic (
merge,where <coloana> is null). - Un pachet sta singur in scriptul lui, fara alt DDL sau DML alaturi: modificarile de tabele si curateniile de date merg in scripturi separate, cu numar propriu.
- Comentarii strict necesare, ca in cod: antet de 4-5 randuri (data + autor, ce e obiectul, ce
contract are), fara referinte la planuri, stories, propuneri, decizii sau erori, fara trimiteri la
rapoartele din
docs/, fara justificarea alegerilor si fara istoricul modificarii. Regula completa si lista de interdictii:reguli_lucru.md, punctul 2.
Optiuni de meniu si drepturi (co_..._OBIECTE.sql)
O optiune noua de meniu inseamna un rand in DEF_OBIECTE (catalogul de obiecte al programului,
arbore prin ID_TATA, cu COD de doua cifre pe fiecare nivel) plus cate un rand in
DEF_GRUP_DREPT_OBIECTE pentru fiecare grup care primeste dreptul. Ambele stau in
CONTAFIN_ORACLE, deci scriptul are prefix co_.
ID_OBIECT se aloca in dezvoltare si se trece ca literal in script. Se insereaza intai obiectul
pe CONTAFIN_ORACLE@ROA_CENTRAL, unde trigger-ul TRG_DEF_OBIECTE_BEFOINS ii da un ID din
SEQ_DEF_OBIECTE; ID-ul obtinut se scrie apoi in script si ajunge identic la toti clientii, cu
merge ... on (a.id_obiect = <literal>). Catalogul ramane astfel acelasi peste tot, iar ID_TATA
poate fi si el literal.
Niciodata insert fara ID_OBIECT. Trigger-ul completeaza din secventa doar cand coloana e
NULL sau 0, iar la client SEQ_DEF_OBIECTE e mult in urma fata de MAX(ID_OBIECT) (nu avanseaza
la insert-urile cu ID explicit): NEXTVAL intoarce un ID deja folosit si scriptul pica pe PK_DO
cu ORA-00001. Secventa nu se resincronizeaza — pe schemele de client e inerta prin design.
Grupurile nu se dau niciodata ca ID-uri fixe. Fiecare client isi defineste propriile grupuri,
deci acelasi ID_GRUP inseamna altceva la fiecare (42 e VIZUALIZARE pe dev si
ROMFAST - CONTRACTE in productie). Drepturile se copiaza de la o optiune sora din acelasi nod:
merge into def_grup_drept_obiecte a using
(select distinct <id_obiect_nou> as id_obiect, g.id_grup, -3 as id_utilop, sysdate as dataora, 0 as sters
from def_obiecte s
join def_grup_drept_obiecte g on g.id_obiect = s.id_obiect and g.sters = 0
where s.id_tata = <id_nod> and s.id_obiect <> <id_obiect_nou> and nvl(s.sters, 0) = 0) b
on (a.id_obiect = b.id_obiect and a.id_grup = b.id_grup)
when not matched then
insert (id_obiect, id_grup, id_utilop, dataora, sters) values (b.id_obiect, b.id_grup, b.id_utilop, b.dataora, b.sters);
DEF_OBIECTE.STERS accepta NULL, deci filtrul pe el se scrie nvl(s.sters, 0) = 0 — s.sters = 0
sare tacut peste randurile cu NULL, fara nicio eroare. In DEF_GRUP_DREPT_OBIECTE si DEF_GRUP
coloana e NOT NULL.
ID_UTILOP = -3 e utilizatorul de migrare, folosit de toate scripturile co_..._OBIECTE.sql.
Optiunea devine vizibila prin COMUN\programe\acces_meniu.prg, care citeste
contafin_oracle.vdef_util_obiecte pentru utilizatorul si programul curent si activeaza obiectele
de clasa cw a caror cheie (literele nodurilor + COD) se regaseste acolo.
Compatibilitate cu serverele clientilor
Serverul de dezvoltare e mai nou decat serverele clientilor, deci un script care trece local poate pica la client si opri actualizarea.
Parcul de servere (03.08.2026): un client pe Oracle 10.2 (ROMCONSTRUCT), cativa pe XE 11 si 11g standard, restul pe XE 18/19/21 si 18/21.
Regula: orice script care ajunge in comune se scrie la nivelul Oracle 10.2 si trebuie sa ruleze pe 10.2 si pe 11.x. Numitorul comun e 10.2 — nu se folosesc facilitati 11g si cu atat mai putin 12c+, oricat de comod ar fi pe dev. Proba inainte de publicare se face pe serverul cel mai vechi (ROMCONSTRUCT), nu pe dev.
Constructii care merg pe dev si pica mai jos:
| Constructie | Disponibila de la | Ce iese sub ea |
|---|---|---|
| identificator peste 30 de caractere (tabela, index, constrangere, coloana) | 12.2 | ORA-00972 |
REGEXP_COUNT |
11.1 | ORA-00904 in SQL / PLS-00201 in PL/SQL |
CONTINUE (instructiune PL/SQL) |
11.1 | PLS-00201: identificatorul 'CONTINUE' trebuie declarat |
LISTAGG |
11.2 | ORA-00904 |
PIVOT / UNPIVOT |
11.1 | eroare de sintaxa |
trigger compus (COMPOUND TRIGGER) |
11.1 | eroare de compilare |
secventa.NEXTVAL direct intr-o atribuire PL/SQL |
11.1 | PLS-00357 (pe 10g: select ... into din dual) |
FETCH FIRST n ROWS, CROSS APPLY, LATERAL |
12.1 | eroare de sintaxa (pe 10g/11g: rownum) |
IDENTITY, DEFAULT ON NULL, coloane invizibile |
12.1 | eroare de sintaxa |
VALIDATE_CONVERSION, CAST ... DEFAULT ON CONVERSION ERROR |
12.2 | ORA-00904 |
FORALL cu campuri de record din colectie (S(i).camp) |
11.1 | PLS-00436 / PLS-00382 |
Editiile XE adauga limite proprii, independent de sintaxa: XE 11.2 nu are partitionare, executie paralela si nici masina virtuala Java in baza; XE 18/19/21 au setul de facilitati al editiei mari, dar plafonate pe resurse (12 GB de date, 2 GB RAM, 2 fire de executie). Deci nimic care sa depinda de partitionare sau de Java in baza, si nicio operatie care sa presupuna spatiu/memorie de server mare.
Plus, independent de versiune: un obiect nu se poate referi la ceva creat de un script ulterior.
Pe dev obiectul exista deja, deci pachetul compileaza; la client scriptele se aplica in ordine si
iese ORA-00942 / corp invalid. Cand un script creeaza o tabela si altul un pachet care o foloseste,
tabela trebuie sa fie prima in ordinea YYYY_MM_DD_NN.
Un pachet care nu are echivalent 10g se livreaza ca varianta separata pentru serverul acela
(ex. ff_..._PACK_CONTAFIN_10G_ROMCONSTRUCT.pck). La aplicarea manuala a unei astfel de variante se
compileaza doar PACKAGE BODY-ul: recrearea specificatiei invalideaza dependentele si da
ORA-04068 utilizatorilor conectati. Inainte, verifica ca specificatia din fisier e identica cu cea
de pe server.
Verificarea erorii se face in C:\DMPDIR\script_master.log de pe serverul clientului
(depanare-pack-update.md) — nu apare in UPD_LOG.
Numerotare si versiune_db.txt
Numele scriptului: <prefix>_YYYY_MM_DD_NN_<subiect>.sql. Prefixe in uz: ff (schema fiecarei
firme), co (CONTAFIN_ORACLE), sys, ris, rf.
NNe o secventa unica pe zi, comuna tuturor prefixelor — un numar consumat de unco_nu se reia intr-unff_din aceeasi zi si invers.- In
versiune_db.txt(radacina aplicatiei) se trece doar versiunea ultimului scriptff_: programele se conecteaza pe schema firmei, nu peCONTAFIN_ORACLE, deci markerul urmareste numai migrarile aplicate acolo.