Files
ROMFASTSQL/proxmox/lxc108-oracle/roa-windows-setup/sql/sys-objects.sql
Marius 7fce925349 feat(oracle): kit de instalare la client + corectarea lipsurilor din instalare
Blocul de instalare/migrare Oracle 21c XE, terminat si validat pe VM 302.

Kit de instalare (nou)

  scripts/build-client-kit.ps1 exporta CONTAFIN_ORACLE si FIRMANOUA de pe
  LXC 108 (PDB ROA2, nu ROA - ROA e productia ROA_CENTRAL), le aduce local
  prin cele trei hopuri container -> LXC -> host -> statie, le redenumeste la
  numele pe care le asteapta scripturile si le impacheteaza cu o copie a
  directorului roa-windows-setup. Citeste logul expdp si raporteaza cate
  firme are NOM_FIRME, ca sa nu plece din greseala datele unui client.

  roa-windows-setup/INSTALEAZA.cmd ruleaza pasii 01..08 fara "set /p", deci
  merge si prin SSH - RunAll.cmd nu poate fi rulat neinteractiv. Trateaza
  corect codul 5 de la pasul 03 si se opreste la prima eroare reala.

Corectii

  01-setup-database.ps1 nu mai scrie SQLNET.RECV_TIMEOUT / SEND_TIMEOUT in
  sqlnet.ora. Le hardcoda la 30 s, iar fisierul e citit si de impdp: in timpul
  unui import serverul poate lucra minute fara sa trimita un pachet, clientul
  murea cu ORA-12609 iar scriptul raporta esec pentru un import care se
  terminase cu bine pe server. Reprodus si reparat pe VM 302.

  01-setup-database.ps1: Step 4c optional (-ResetSystemPassword) care curata
  EXPIRED(GRACE) pe SYSTEM in CDB root; ALTER PROFILE opreste expirarile
  viitoare dar nu reseteaza un cont deja intrat in gratie.

  uninstall-roa.sql: retry la DROP USER dupa KILL SESSION, plus un bloc final
  de verdict care numara ce a ramas si iese cu ORA-20900 daca baza nu e
  curata. Pana acum toate sectiunile prindeau exceptiile in WHEN OTHERS si
  scriptul tiparea "UNINSTALL COMPLETE" chiar si cand un user supravietuise,
  iar instalarea urmatoare dadea ORA-31684 in lant. 99-uninstall-roa.ps1
  propaga codul de iesire.

  08-post-install-config.ps1: Step 7b seteaza SMTP_OUT_SERVER si ACL-ul de
  retea pentru CONTAFIN_ORACLE. UTL_MAIL se instala si primea EXECUTE, adica
  destul cat sa compileze, dar nu si cat sa trimita. Privilegiul resolve nu
  accepta interval de porturi (ORA-24244), deci se acorda separat de connect.

  07-verify-installation.ps1: sectiune noua care verifica prezenta lui
  FIRMANOUA.dmp in DMPDIR si o raporteaza ca eroare daca lipseste. Fara el,
  adaugarea unei firme noi pica in DBMS_DATAPUMP.ADD_FILE peste luni de la
  instalare, cand nimeni nu mai leaga eroarea de instalare.

  configure-profile.sql: antetul spune ca e unealta de remediere manuala, nu
  parte din flux; pas nou la final pentru CDB root.

Documentatie

  README-ul roa-windows-setup descrie acum explicit cele doua scenarii -
  instalare pe curat si migrare - de unde se iau DMP-urile sablon, si capcana
  ORA-12609. Handoff-urile de sesiune au fost sterse; ce era durabil in ele a
  intrat in README-uri si in docs/diagnostic-spatiu-clienti.md.

Validare pe VM 302: ciclu complet din kit, instalare pe curat, verificarea
finala "[OK] All checks passed!".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
2026-08-25 18:05:56 +03:00

1182 lines
45 KiB
MySQL

-- ============================================================================
-- SYS CUSTOM OBJECTS FOR ROA APPLICATION
-- ============================================================================
-- Oracle 21c/18c Compatible Version
-- Updated: January 2026
--
-- This file contains all custom SYS objects required by the ROA application:
-- - Tables: AUTH_DETALII, AUTH_SERII, INFO
-- - View: VAUTH_SERII
-- - Sequence: SEQ_AUTH_SERII
-- - Package: AUTH_PACK (uses DBMS_CRYPTO for Oracle 21c compatibility)
-- - Procedures: EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS, pINFO
--
-- IMPORTANT: Run this script as SYS with SYSDBA privileges
--
-- Usage:
-- sqlplus sys/password@service as sysdba @sys-objects.sql
--
-- ============================================================================
SET SERVEROUTPUT ON
SET FEEDBACK ON
WHENEVER SQLERROR CONTINUE
PROMPT
PROMPT ========================================
PROMPT Installing SYS Custom Objects
PROMPT ========================================
PROMPT
-- ============================================================================
-- SECTION 1: TABLES
-- ============================================================================
PROMPT [1/10] Creating SYS.AUTH_DETALII table...
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count FROM dba_tables
WHERE owner = 'SYS' AND table_name = 'AUTH_DETALII';
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE(' Table AUTH_DETALII already exists, skipping.');
ELSE
EXECUTE IMMEDIATE '
CREATE TABLE SYS.AUTH_DETALII (
DETALII VARCHAR2(15) NOT NULL
) TABLESPACE SYSTEM';
DBMS_OUTPUT.PUT_LINE(' Table AUTH_DETALII created.');
END IF;
END;
/
PROMPT [2/10] Creating SYS.AUTH_SERII table...
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count FROM dba_tables
WHERE owner = 'SYS' AND table_name = 'AUTH_SERII';
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE(' Table AUTH_SERII already exists, skipping.');
ELSE
EXECUTE IMMEDIATE '
CREATE TABLE SYS.AUTH_SERII (
ID_SERIE NUMBER(5,0) NOT NULL,
ID_PROGRAM NUMBER(5,0) NOT NULL,
SERIE RAW(128) NOT NULL,
STERS NUMBER(1,0) DEFAULT 0 NOT NULL,
DATAORA DATE DEFAULT SYSDATE NOT NULL,
ID_UTIL NUMBER(5,0) NOT NULL,
DATAORAS DATE,
ID_UTILS NUMBER(5,0),
CONSTRAINT PK_AUTH_SERII PRIMARY KEY (ID_SERIE)
) TABLESPACE SYSTEM';
DBMS_OUTPUT.PUT_LINE(' Table AUTH_SERII created.');
END IF;
END;
/
PROMPT [3/10] Creating SYS.INFO table (logging)...
-- IMPORTANT: SYS.INFO e log de aplicatie, nu obiect de dictionar - SYS.pINFO scrie ~7 randuri la
-- fiecare conectare (~13.500 randuri / ~2 MB pe luna) si nimic nu o citeste. Tinuta in SYSTEM,
-- umple tablespace-ul dictionarului si **orice** script de actualizare pica apoi cu
-- ORA-01653 (SIGMA 03.08.2026, AUTOMOTIVE 08.08.2026). De aceea se creeaza in tablespace-ul
-- aplicatiei, iar cresterea e marginita de jobul SYSINFO_PURJARE_ZILNIC (scheduler-jobs.sql).
DECLARE
v_count NUMBER;
v_ts VARCHAR2(30);
BEGIN
SELECT COUNT(*) INTO v_count FROM dba_tables
WHERE owner = 'SYS' AND table_name = 'INFO';
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE(' Table INFO already exists, skipping.');
ELSE
SELECT MAX(tablespace_name) INTO v_ts
FROM dba_tablespaces WHERE tablespace_name = 'ROA';
IF v_ts IS NULL THEN
v_ts := 'SYSTEM';
DBMS_OUTPUT.PUT_LINE(' WARNING: tablespace ROA missing - INFO falls back to SYSTEM.');
DBMS_OUTPUT.PUT_LINE(' Run create-tablespace.sql first, then move it:');
DBMS_OUTPUT.PUT_LINE(' ALTER TABLE SYS.INFO MOVE TABLESPACE ROA LOB (INFO) STORE AS (TABLESPACE ROA);');
END IF;
EXECUTE IMMEDIATE '
CREATE TABLE SYS.INFO (
INFO CLOB,
DATAORA TIMESTAMP(6) DEFAULT SYSTIMESTAMP,
LOCATIA VARCHAR2(200) NULL
) TABLESPACE ' || v_ts || ' LOB (INFO) STORE AS (TABLESPACE ' || v_ts || ')';
DBMS_OUTPUT.PUT_LINE(' Table INFO created in tablespace ' || v_ts || '.');
END IF;
END;
/
-- ============================================================================
-- SECTION 2: SEQUENCE
-- ============================================================================
PROMPT [4/10] Creating SYS.SEQ_AUTH_SERII sequence...
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count FROM dba_sequences
WHERE sequence_owner = 'SYS' AND sequence_name = 'SEQ_AUTH_SERII';
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE(' Sequence SEQ_AUTH_SERII already exists, skipping.');
ELSE
EXECUTE IMMEDIATE '
CREATE SEQUENCE SYS.SEQ_AUTH_SERII
MINVALUE 1
MAXVALUE 99999
INCREMENT BY 1
START WITH 1
NOCACHE
NOORDER
NOCYCLE';
DBMS_OUTPUT.PUT_LINE(' Sequence SEQ_AUTH_SERII created.');
END IF;
END;
/
-- ============================================================================
-- SECTION 3: LOGGING PROCEDURE (pINFO)
-- ============================================================================
PROMPT [5/10] Creating SYS.pINFO procedure (logging)...
CREATE OR REPLACE PROCEDURE SYS.pINFO(
p_info IN CLOB,
p_locatia IN VARCHAR2 DEFAULT NULL
) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO SYS.INFO (INFO, DATAORA, LOCATIA)
VALUES (p_info, SYSTIMESTAMP, p_locatia);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
-- Silently fail to avoid breaking caller
ROLLBACK;
END pINFO;
/
-- ============================================================================
-- SECTION 4: AUTH_PACK PACKAGE (Oracle 21c compatible with DBMS_CRYPTO)
-- ============================================================================
PROMPT [6/10] Creating SYS.AUTH_PACK package specification...
CREATE OR REPLACE PACKAGE SYS.AUTH_PACK IS
-- ========================================================================
-- AUTH_PACK - License and Authentication Management
-- ========================================================================
-- Author : MARIUS.ATANASIU
-- Created : 11/5/2005
-- Updated : 2026-01-14 - Migrated to Oracle 21c with DBMS_CRYPTO
--
-- Purpose:
-- Manages ROA application licensing, including:
-- - Program license verification on login
-- - User count verification per program
-- - License expiration checks
-- - Company count limits
-- ========================================================================
PROCEDURE verifica_program;
PROCEDURE verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2);
PROCEDURE verifica_licenta_luna(
v_an IN NUMBER,
v_luna IN NUMBER,
v_tip IN NUMBER
);
PROCEDURE verifica_numar_firme;
PROCEDURE adauga_serie(
V_ID_PROGRAM IN NUMBER,
V_SERIE IN VARCHAR2,
V_ID_UTILAD IN NUMBER
);
PROCEDURE sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER);
PROCEDURE verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW);
FUNCTION selecteaza_serie(V_ID_PROGRAM IN NUMBER) RETURN VARCHAR2;
FUNCTION selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) RETURN NUMBER;
FUNCTION selecteaza_data_val(V_ID_PROGRAM IN NUMBER) RETURN DATE;
FUNCTION decripteaza_serie(
V_ID_PROGRAM IN NUMBER,
V_SERIE IN RAW,
V_DATAORA IN DATE
) RETURN VARCHAR2;
FUNCTION decripteaza_nr_util(V_SERIEC IN VARCHAR2) RETURN NUMBER;
FUNCTION decripteaza_data_val(
V_SERIEC IN VARCHAR2,
V_ZI IN VARCHAR2
) RETURN DATE;
FUNCTION hextodec(V_HEXA IN VARCHAR2) RETURN NUMBER;
FUNCTION dectohex(V_NUMAR IN NUMBER) RETURN VARCHAR2;
END AUTH_PACK;
/
PROMPT [7/10] Creating SYS.AUTH_PACK package body...
CREATE OR REPLACE PACKAGE BODY SYS.AUTH_PACK IS
-- ========================================================================
-- MODIFICATION HISTORY:
-- 2026-01-14: Migration Oracle 10g -> Oracle 21c
-- - Replaced DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt with DBMS_CRYPTO.DECRYPT
-- - Using ENCRYPT_3DES_2KEY (16-byte key) + CHAIN_CBC + PAD_ZERO
-- - Added PINFO logging calls for debugging
-- ========================================================================
---------------------------------------------------------------------------
-- VERIFICA_PROGRAM
-- Called on database login (via LOGON trigger) to verify license
---------------------------------------------------------------------------
PROCEDURE verifica_program IS
v_program VARCHAR2(256);
v_modul VARCHAR2(256);
v_sid NUMBER(16);
BEGIN
BEGIN
SELECT sid, UPPER(TRIM(program)), UPPER(TRIM(module))
INTO v_sid, v_program, v_modul
FROM v$session
WHERE audsid = USERENV('SESSIONID')
AND audsid != 0
AND ROWNUM = 1
AND STATUS <> 'KILLED';
PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
IF v_program NOT IN (
'ROASTART.EXE',
'PLSQLDEV.EXE',
'ROAGEN.EXE',
'ROASUPORT.EXE',
'EXPDP.EXE',
'IMPDP.EXE',
'APSNET_WP.EXE',
'W3WP.EXE',
'RUBY.EXE',
'SQLPLUS.EXE',
'TASKS.EXE',
'VFP9.EXE',
'ROAEFACTURA.EXE',
'WEBDEV.WEBSERVER.EXE',
'ROA2COCACOLA.EXE',
'GENERARESCRIPT.EXE',
'ROAACTUALIZARI.EXE',
'EXP.EXE',
'IMP.EXE'
) AND USER NOT IN (
'SYS',
'SYSTEM',
'DBSNMP',
'CTXSYS',
'MDSYS',
'DIP',
'SYSMAN',
'WMSYS'
) THEN
PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
IF v_program <> v_modul THEN
RAISE_APPLICATION_ERROR(-20000, 'Acces interzis!');
END IF;
PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
IF NOT V_PROGRAM LIKE 'ORACLE%' THEN
auth_pack.verifica_licenta(v_sid, v_program);
END IF;
PINFO('4 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_program := NULL;
END;
END verifica_program;
---------------------------------------------------------------------------
-- VERIFICA_LICENTA
-- Verifies license exists for program and checks user count by IP
---------------------------------------------------------------------------
PROCEDURE verifica_licenta(v_sid IN NUMBER, v_program IN VARCHAR2) IS
v_serie VARCHAR2(256);
v_seriec VARCHAR2(256);
v_nr_util NUMBER(5);
v_utilizatori NUMBER(5);
v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE;
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
v_dataora DATE;
v_data_val DATE;
v_zi VARCHAR2(2);
BEGIN
V_NUME_PROGRAM := TRIM(REPLACE(v_program, '.EXE'));
BEGIN
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
FROM SYN_NOM_PROGRAME A
LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM
WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
AND B.STERS = 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
PINFO('1 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
RAISE_APPLICATION_ERROR(-20000,
'Nu aveti licenta pentru ' || V_NUME_PROGRAM || '!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi introdusa prin programul ROASUPORT!');
END;
PINFO('2 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
v_zi := LPAD(EXTRACT(DAY FROM v_dataora), 2, '0');
v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora);
v_utilizatori := auth_pack.decripteaza_nr_util(v_seriec);
v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi);
IF v_utilizatori > 0 THEN
-- Count distinct IPs (client_info) connected with same program
-- excluding current session's IP
SELECT COUNT(DISTINCT client_info)
INTO v_nr_util
FROM v$session
WHERE UPPER(TRIM(PROGRAM)) = v_program
AND SID != v_sid
AND STATUS <> 'KILLED'
AND NVL(client_info, 'x') <> SYS_CONTEXT('userenv', 'ip_address');
IF v_nr_util >= v_utilizatori THEN
RAISE_APPLICATION_ERROR(-20000,
'Ati depasit numarul de licente (' || v_utilizatori ||
') pentru programul ' || v_nume_program || ' !' ||
CHR(13) || CHR(10) ||
' Licenta poate fi reinnoita prin programul ROASUPORT!');
END IF;
ELSE
RAISE_APPLICATION_ERROR(-20000,
'Seria introdusa pentru acest program nu este corecta!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi modificata prin programul ROASUPORT!');
END IF;
PINFO('3 LOGIN ' || V_PROGRAM || ' USER ' || USER, 'SYS.AUTH2');
END verifica_licenta;
---------------------------------------------------------------------------
-- VERIFICA_LICENTA_LUNA
-- Verifies license for opening a new month (triggered on CALENDAR insert)
---------------------------------------------------------------------------
PROCEDURE verifica_licenta_luna(
v_an IN NUMBER,
v_luna IN NUMBER,
v_tip IN NUMBER
) IS
v_serie VARCHAR2(256);
v_seriec VARCHAR2(256);
v_nume_program1 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
v_nume_program2 SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASAL';
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
v_dataora DATE;
v_data_val DATE;
v_zi VARCHAR2(2);
BEGIN
BEGIN
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
FROM SYN_NOM_PROGRAME A
LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM
WHERE UPPER(TRIM(A.DENUMIRE)) =
DECODE(V_TIP, 1, V_NUME_PROGRAM1, 2, V_NUME_PROGRAM2, 'XYZ')
AND B.STERS = 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,
'Nu aveti licenta pentru deschiderea de luna noua!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi introdusa prin programul ROASUPORT!');
END;
v_zi := LPAD(EXTRACT(DAY FROM v_dataora), 2, '0');
v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora);
v_data_val := auth_pack.decripteaza_data_val(v_seriec, v_zi);
IF v_data_val < TO_DATE(v_an || v_luna, 'YYYYMM') THEN
RAISE_APPLICATION_ERROR(-20000,
'Licenta pentru acest program a expirat!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi reinnoita prin programul ROASUPORT!');
END IF;
END verifica_licenta_luna;
---------------------------------------------------------------------------
-- VERIFICA_NUMAR_FIRME
-- Verifies company count doesn't exceed license limit
---------------------------------------------------------------------------
PROCEDURE verifica_numar_firme IS
v_serie VARCHAR2(256);
v_seriec VARCHAR2(256);
v_nume_program SYN_NOM_PROGRAME.DENUMIRE%TYPE := 'ROASTART';
v_id_program CONTAFIN_ORACLE.NOM_PROGRAME.ID_PROGRAM%TYPE;
v_dataora DATE;
V_NR_MAX_FIRME NUMBER(10) := 0;
V_NR_FIRME NUMBER(10) := 0;
BEGIN
BEGIN
SELECT A.ID_PROGRAM, B.SERIE, B.DATAORA
INTO V_ID_PROGRAM, V_SERIE, V_DATAORA
FROM SYN_NOM_PROGRAME A
LEFT JOIN AUTH_SERII B ON A.ID_PROGRAM = B.ID_PROGRAM
WHERE UPPER(TRIM(A.DENUMIRE)) = V_NUME_PROGRAM
AND B.STERS = 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20000,
'Nu aveti licenta pentru deschiderea unei firme noi!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi introdusa prin programul ROASUPORT!');
END;
v_seriec := auth_pack.decripteaza_serie(v_id_program, v_serie, v_dataora);
V_NR_MAX_FIRME := auth_pack.decripteaza_nr_util(V_SERIEC);
SELECT COUNT(*)
INTO V_NR_FIRME
FROM SYN_NOM_FIRME
WHERE STERS = 0
AND NVL(ID_MAMA, 0) = 0;
IF V_NR_FIRME >= V_NR_MAX_FIRME THEN
RAISE_APPLICATION_ERROR(-20000,
'Aveti licenta pentru maxim ' || V_NR_MAX_FIRME ||
' firme (' || V_NR_FIRME || ' firme deja definite)!' ||
CHR(13) || CHR(10) ||
' Licenta poate fi introdusa prin programul ROASUPORT!');
END IF;
END verifica_numar_firme;
---------------------------------------------------------------------------
-- ADAUGA_SERIE
-- Adds a new license serial number for a program
---------------------------------------------------------------------------
PROCEDURE adauga_serie(
V_ID_PROGRAM IN NUMBER,
V_SERIE IN VARCHAR2,
V_ID_UTILAD IN NUMBER
) IS
V_ID_SERIE AUTH_SERII.ID_SERIE%TYPE;
V_SERIER AUTH_SERII.SERIE%TYPE;
eroare_de_conversie EXCEPTION;
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
BEGIN
BEGIN
V_SERIER := HEXTORAW(V_SERIE);
EXCEPTION
WHEN eroare_de_conversie THEN
RAISE_APPLICATION_ERROR(-20000, 'Aceasta serie nu este valida!');
END;
auth_pack.verifica_serie(V_ID_PROGRAM, V_SERIER);
SELECT SEQ_AUTH_SERII.NEXTVAL INTO V_ID_SERIE FROM DUAL;
INSERT INTO AUTH_SERII (ID_SERIE, ID_PROGRAM, SERIE, ID_UTIL)
VALUES (V_ID_SERIE, V_ID_PROGRAM, V_SERIER, V_ID_UTILAD);
END adauga_serie;
---------------------------------------------------------------------------
-- STERGE_SERIE
-- Marks a license serial as deleted (soft delete)
---------------------------------------------------------------------------
PROCEDURE sterge_serie(V_ID_PROGRAM IN NUMBER, V_ID_UTILS IN NUMBER) IS
BEGIN
UPDATE AUTH_SERII
SET STERS = 1, ID_UTILS = V_ID_UTILS, DATAORAS = SYSDATE
WHERE ID_PROGRAM = V_ID_PROGRAM
AND STERS = 0;
END sterge_serie;
---------------------------------------------------------------------------
-- SELECTEAZA_SERIE
-- Returns the hex-encoded serial for a program
---------------------------------------------------------------------------
FUNCTION selecteaza_serie(V_ID_PROGRAM IN NUMBER) RETURN VARCHAR2 IS
V_SERIE AUTH_SERII.SERIE%TYPE;
V_SERIEC VARCHAR2(256);
eroare_de_conversie EXCEPTION;
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
BEGIN
BEGIN
SELECT SERIE
INTO V_SERIE
FROM AUTH_SERII
WHERE ID_PROGRAM = V_ID_PROGRAM
AND STERS = 0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
V_SERIE := NULL;
END;
BEGIN
V_SERIEC := TRIM(RAWTOHEX(V_SERIE));
EXCEPTION
WHEN eroare_de_conversie THEN
V_SERIEC := NULL;
END;
RETURN V_SERIEC;
END selecteaza_serie;
---------------------------------------------------------------------------
-- SELECTEAZA_NR_UTIL
-- Returns the number of licensed users for a program
---------------------------------------------------------------------------
FUNCTION selecteaza_nr_util(V_ID_PROGRAM IN NUMBER) RETURN NUMBER IS
V_SERIE AUTH_SERII.SERIE%TYPE;
V_DATAORA DATE;
V_NR_UTILIZATORI NUMBER(4);
V_SERIEC VARCHAR2(64);
BEGIN
BEGIN
SELECT SERIE, DATAORA
INTO V_SERIE, V_DATAORA
FROM AUTH_SERII
WHERE ID_PROGRAM = V_ID_PROGRAM
AND STERS = 0;
V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, V_DATAORA);
V_NR_UTILIZATORI := auth_pack.decripteaza_nr_util(V_SERIEC);
EXCEPTION
WHEN NO_DATA_FOUND THEN
V_NR_UTILIZATORI := 0;
END;
RETURN V_NR_UTILIZATORI;
END selecteaza_nr_util;
---------------------------------------------------------------------------
-- SELECTEAZA_DATA_VAL
-- Returns the license expiration date for a program
---------------------------------------------------------------------------
FUNCTION selecteaza_data_val(V_ID_PROGRAM IN NUMBER) RETURN DATE IS
V_SERIE AUTH_SERII.SERIE%TYPE;
V_DATAORA DATE;
V_DATA_VAL DATE;
V_SERIEC VARCHAR2(64);
V_ZI VARCHAR2(2);
BEGIN
BEGIN
SELECT SERIE, DATAORA
INTO V_SERIE, V_DATAORA
FROM AUTH_SERII
WHERE ID_PROGRAM = V_ID_PROGRAM
AND STERS = 0;
V_SERIEC := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, V_DATAORA);
V_ZI := LPAD(EXTRACT(DAY FROM V_DATAORA), 2, '0');
V_DATA_VAL := auth_pack.decripteaza_data_val(V_SERIEC, V_ZI);
EXCEPTION
WHEN NO_DATA_FOUND THEN
V_DATA_VAL := NULL;
END;
RETURN V_DATA_VAL;
END selecteaza_data_val;
---------------------------------------------------------------------------
-- VERIFICA_SERIE
-- Validates a license serial checksum
---------------------------------------------------------------------------
PROCEDURE verifica_serie(V_ID_PROGRAM IN NUMBER, V_SERIE IN RAW) IS
v_seriedec VARCHAR2(256);
v_checksum NUMBER(2);
v_suma NUMBER(2) := 0;
BEGIN
v_seriedec := auth_pack.decripteaza_serie(V_ID_PROGRAM, V_SERIE, SYSDATE);
v_checksum := auth_pack.hextodec(SUBSTR(v_seriedec, LENGTH(v_seriedec), 1));
FOR i IN 1 .. LENGTH(v_seriedec) - 1 LOOP
v_suma := v_suma + auth_pack.hextodec(SUBSTR(v_seriedec, i, 1));
END LOOP;
IF MOD(v_suma + v_checksum, 16) <> 0 THEN
RAISE_APPLICATION_ERROR(-20000, 'Seria introdusa nu este valida!');
END IF;
END verifica_serie;
---------------------------------------------------------------------------
-- DECRIPTEAZA_SERIE
-- Decrypts a license serial using DBMS_CRYPTO (Oracle 21c compatible)
-- Replaced DBMS_OBFUSCATION_TOOLKIT.DES3Decrypt
---------------------------------------------------------------------------
FUNCTION decripteaza_serie(
V_ID_PROGRAM IN NUMBER,
V_SERIE IN RAW,
V_DATAORA IN DATE
) RETURN VARCHAR2 IS
v_denumire CONTAFIN_ORACLE.NOM_PROGRAME.DENUMIRE%TYPE;
v_id_client NUMBER(4);
v_cheie RAW(16);
v_serieval RAW(256);
v_seriedec VARCHAR2(32);
v_valoare NUMBER(2);
eroare_de_conversie EXCEPTION;
PRAGMA EXCEPTION_INIT(eroare_de_conversie, -6502);
BEGIN
IF V_SERIE IS NOT NULL THEN
SELECT SUBSTR(a.denumire, 4, 5)
INTO V_DENUMIRE
FROM SYN_NOM_PROGRAME A
WHERE A.ID_PROGRAM = V_ID_PROGRAM;
SELECT TO_NUMBER(DETALII) INTO V_ID_CLIENT FROM AUTH_DETALII;
-- Build 16-byte key for 3DES-2KEY
v_cheie := UTL_RAW.CAST_TO_RAW(
RPAD(
LPAD(v_id_program, 3, '0') ||
LPAD(v_id_client, 4, '0') ||
RPAD(v_denumire, 5, CHR(4)) ||
LPAD(TO_CHAR(v_dataora, 'IWYY'), 4, '0'),
16,
'X'
)
);
-- Use DBMS_CRYPTO instead of DBMS_OBFUSCATION_TOOLKIT
-- ENCRYPT_3DES_2KEY for 16-byte keys, PAD_ZERO for compatibility
v_serieval := DBMS_CRYPTO.DECRYPT(
src => v_serie,
typ => DBMS_CRYPTO.ENCRYPT_3DES_2KEY +
DBMS_CRYPTO.CHAIN_CBC +
DBMS_CRYPTO.PAD_ZERO,
key => v_cheie
);
BEGIN
FOR i IN 1 .. LENGTH(v_serieval) / 2 LOOP
v_valoare := TO_NUMBER(SUBSTR(v_serieval, 2 * i - 1, 2));
IF v_valoare > 40 THEN
v_seriedec := v_seriedec || auth_pack.dectohex(v_valoare - 31);
ELSE
v_seriedec := v_seriedec || (v_valoare - 30);
END IF;
END LOOP;
EXCEPTION
WHEN eroare_de_conversie THEN
RAISE_APPLICATION_ERROR(-20100, 'Seria introdusa nu este valida!');
END;
ELSE
v_seriedec := NULL;
END IF;
RETURN v_seriedec;
END decripteaza_serie;
---------------------------------------------------------------------------
-- DECRIPTEAZA_NR_UTIL
-- Extracts user count from decrypted serial
---------------------------------------------------------------------------
FUNCTION decripteaza_nr_util(V_SERIEC IN VARCHAR2) RETURN NUMBER IS
BEGIN
IF V_SERIEC IS NOT NULL THEN
RETURN TO_NUMBER(SUBSTR(v_seriec, 1, 4));
ELSE
RETURN 0;
END IF;
END decripteaza_nr_util;
---------------------------------------------------------------------------
-- DECRIPTEAZA_DATA_VAL
-- Extracts expiration date from decrypted serial
---------------------------------------------------------------------------
FUNCTION decripteaza_data_val(
V_SERIEC IN VARCHAR2,
V_ZI IN VARCHAR2
) RETURN DATE IS
v_luna VARCHAR2(2);
BEGIN
IF V_SERIEC IS NOT NULL THEN
v_luna := LPAD(auth_pack.hextodec(SUBSTR(v_seriec, 5, 1)), 2, '0');
RETURN LAST_DAY(TO_DATE(v_luna || SUBSTR(v_seriec, 6, 2), 'MMYY'));
ELSE
RETURN NULL;
END IF;
END decripteaza_data_val;
---------------------------------------------------------------------------
-- HEXTODEC
-- Converts a hex character to decimal
---------------------------------------------------------------------------
FUNCTION hextodec(V_HEXA IN VARCHAR2) RETURN NUMBER IS
v_numar NUMBER(2);
BEGIN
IF ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 48 AND 57 OR
ASCII(UPPER(TRIM(V_HEXA))) BETWEEN 65 AND 70 THEN
CASE UPPER(TRIM(V_HEXA))
WHEN 'A' THEN v_numar := 10;
WHEN 'B' THEN v_numar := 11;
WHEN 'C' THEN v_numar := 12;
WHEN 'D' THEN v_numar := 13;
WHEN 'E' THEN v_numar := 14;
WHEN 'F' THEN v_numar := 15;
ELSE v_numar := TO_NUMBER(V_HEXA);
END CASE;
ELSE
RAISE_APPLICATION_ERROR(-20000, 'Caracterul nu este valid!');
END IF;
RETURN v_numar;
END hextodec;
---------------------------------------------------------------------------
-- DECTOHEX
-- Converts a decimal to hex character
---------------------------------------------------------------------------
FUNCTION dectohex(V_NUMAR IN NUMBER) RETURN VARCHAR2 IS
v_hexa VARCHAR2(1);
BEGIN
CASE v_numar
WHEN 10 THEN v_hexa := 'A';
WHEN 11 THEN v_hexa := 'B';
WHEN 12 THEN v_hexa := 'C';
WHEN 13 THEN v_hexa := 'D';
WHEN 14 THEN v_hexa := 'E';
WHEN 15 THEN v_hexa := 'F';
ELSE v_hexa := TO_CHAR(V_NUMAR);
END CASE;
RETURN v_hexa;
END dectohex;
END AUTH_PACK;
/
-- ============================================================================
-- SECTION 5: VIEW
-- ============================================================================
PROMPT [8/10] Creating SYS.VAUTH_SERII view...
CREATE OR REPLACE VIEW SYS.VAUTH_SERII (
ID_PROGRAM,
NUME,
SERIE,
NR_UTIL,
DATA_VAL
) AS
SELECT a.id_program,
a.denumire AS nume,
auth_pack.selecteaza_serie(a.id_program) AS serie,
auth_pack.selecteaza_nr_util(a.id_program) AS nr_util,
auth_pack.selecteaza_data_val(a.id_program) AS data_val
FROM syn_nom_programe a
LEFT JOIN syn_def_programe b ON a.id_program = b.ide_program
WHERE b.sters = 0
AND b.instalat = 1;
-- ============================================================================
-- SECTION 6: ADDITIONAL PROCEDURES
-- ============================================================================
PROMPT [9/10] Creating SYS.EXECUTESCRIPTOS, NEWSCHEMA, NEWSCHEMAJOB, UPDATESQLPLUS...
-- ============================================================================
-- Sursa: procedurile SYS de pe ROA_CENTRAL (10.0.20.121:1521/ROA), extrase din
-- dba_source la 2026-08-25. Versiunile anterioare din acest fisier aveau
-- semnaturi inventate, incompatibile cu CONTAFIN_ORACLE.PACK_UPDATE, care apeleaza
-- SYS.Updatesqlplus(tcSqlPlusPath, tcScriptPath). Nu modifica semnaturile fara sa
-- verifici intai apelurile din PACK_UPDATE / PACK_UTILS.
-- ============================================================================
CREATE OR REPLACE PROCEDURE SYS.ExecuteScriptOS(tcPowerShellPath in varchar2,
tcScriptPath in varchar2) as
lcJobName varchar2(500);
begin
lcJobName := 'exec_ps_' || SUBSTR(SYS_GUID(), 1, 8);
DBMS_SCHEDULER.CREATE_JOB(
job_name => lcJobName,
job_action => tcPowerShellPath,
number_of_arguments => 4,
job_type => 'executable',
enabled => FALSE
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 1, '-ExecutionPolicy');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 2, 'Bypass');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 3, '-File');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(lcJobName, 4, tcScriptPath);
DBMS_SCHEDULER.ENABLE(lcJobName);
end ExecuteScriptOS;
/
CREATE OR REPLACE PROCEDURE SYS.NewSchema(tcSchema varchar2,
tnLuna number,
tnAn number) is
lcCommand varchar2(1000);
lcSchemaSursa VARCHAR2(100) := 'FIRMANOUA';
lcSchemaDestinatie VARCHAR2(100) := tcSchema;
lcDumpFile VARCHAR2(100);
lcDumpDir VARCHAR2(100) := 'DMPDIR';
-- lnCount number(10);
lcSql varchar2(1000);
lnAn number := tnAn;
lnLuna number := tnLuna;
ldDataI date;
ldDataF date;
lnZileLucratoare number(10) := 0;
lnOreLucratoare number(10) := 0;
lnMaxAn number(10);
lcLocatie varchar2(100) := 'CREARE FIRMA ' || tcSchema;
h1 NUMBER; -- Data Pump job handle
ind NUMBER; -- Loop index
percent_done NUMBER; -- Percentage of job complete
job_state VARCHAR2(30); -- To keep track of job state
le ku$_LogEntry; -- For WIP and error messages
js ku$_JobStatus; -- The job status from get_status
-- jd ku$_JobDesc; -- The job description from get_status
sts ku$_Status; -- The status object returned by get_status
begin
------------------------------------------------------------------------
-- CREATE THE USER
------------------------------------------------------------------------
/* SELECT COUNT(1)
INTO lnCount
FROM dba_users
WHERE username = UPPER(tcSchema);
IF lnCount <> 0 THEN
EXECUTE IMMEDIATE ('DROP USER ' || tcSchema || ' CASCADE');
END IF;*/
lcCommand := 'create user ' || tcSchema || ' identified by ' || CASE
WHEN upper(tcSchema) like 'TEST%' THEN
'"123"'
ELSE
'ROMFASTSOFT'
END || ' default tablespace ROA
temporary tablespace TEMP
profile DEFAULT';
pinfo(lcCommand, lcLocatie);
execute immediate lcCommand;
------------------------------------------------------------------------
-- GRANT PRIVILEGIES
------------------------------------------------------------------------
lcCommand := 'grant connect to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant resource to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create materialized view to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create procedure to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create sequence to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create table to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create trigger to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create type to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant create view to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant debug connect session to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant select any table to ' || tcSchema;
execute immediate lcCommand;
lcCommand := 'grant unlimited tablespace to ' || tcSchema;
execute immediate lcCommand;
------------------------------------------------------------------------
-- IMPORT DUMP
------------------------------------------------------------------------
-- Create a (user-named) Data Pump job to do a "full" import (everything
-- in the dump file without filtering).
lcDumpFile := lcSchemaSursa || '.dmp';
-- h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);
h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'SCHEMA', NULL, lcSchemaDestinatie);
-- Specify the single dump file for the job (using the handle just returned)
-- and directory object, which must already be defined and accessible
-- to the user running this procedure. This is the dump file created by
-- the export operation in the first example.
-- DBMS_DATAPUMP.ADD_FILE(h1, lcDumpFile, lcDumpDir);
BEGIN
PINFO('DBMS_DATAPUMP.ADD_FILE LOG', lcLocatie);
DBMS_DATAPUMP.ADD_FILE(handle => h1,
filename => lcSchemaDestinatie || '.log',
directory => 'DMPDIR',
filetype => 3);
PINFO('DBMS_DATAPUMP.ADD_FILE DMP', lcLocatie);
DBMS_DATAPUMP.ADD_FILE(handle => h1,
filename => lcDumpFile,
directory => lcDumpDir,
filetype => 1);
-- A metadata remap will map all schema objects from HR to BLAKE.
PINFO('DBMS_DATAPUMP.METADATA_REMAP', lcLocatie);
DBMS_DATAPUMP.METADATA_REMAP(h1,
'REMAP_SCHEMA',
lcSchemaSursa,
lcSchemaDestinatie);
-- If a table already exists in the destination schema, skip it (leave
-- the preexisting table alone). This is the default, but it does not hurt
-- to specify it explicitly.
DBMS_DATAPUMP.SET_PARAMETER(h1, 'TABLE_EXISTS_ACTION', 'SKIP');
-- Start the job. An exception is returned if something is not set up properly.
PINFO('DBMS_DATAPUMP.START_JOB', lcLocatie);
DBMS_DATAPUMP.START_JOB(h1);
------------------------------------------------------------------------
-- The import job should now be running. In the following loop, the job is
-- monitored until it completes. In the meantime, progress information is
-- displayed. Note: this is identical to the export example.
percent_done := 0;
job_state := 'UNDEFINED';
while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
dbms_datapump.get_status(h1,
dbms_datapump.ku$_status_job_error +
dbms_datapump.ku$_status_job_status +
dbms_datapump.ku$_status_wip,
-1,
job_state,
sts);
js := sts.job_status;
-- If the percentage done changed, display the new value.
if js.percent_done != percent_done then
pinfo('*** Job percent done = ' || to_char(js.percent_done),
lcLocatie);
percent_done := js.percent_done;
end if;
-- If any work-in-progress (WIP) or Error messages were received for the job,
-- display them.
if (bitand(sts.mask, dbms_datapump.ku$_status_wip) != 0) then
le := sts.wip;
else
if (bitand(sts.mask, dbms_datapump.ku$_status_job_error) != 0) then
le := sts.error;
else
le := null;
end if;
end if;
if le is not null then
ind := le.FIRST;
while ind is not null loop
-- dbms_output.put_line(le(ind).LogText);
pinfo(le(ind).LogText, lcLocatie);
ind := le.NEXT(ind);
end loop;
end if;
end loop;
-- Indicate that the job finished and gracefully detach from it.
-- dbms_output.put_line('Job has completed');
pinfo('Job has completed', lcLocatie);
-- dbms_output.put_line('Final job state = ' || job_state);
pinfo('Final job state = ' || job_state,
'CREARE FIRMA ' || lcSchemaDestinatie);
------------------------------------------------------------------------
-- POST IMPORT
-- 1. actualizare calendar, sal_calendar, cote_tva
-- CALENDAR
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.CALENDAR SET ANUL = :1, LUNA = :2, AN = TO_CHAR(:3), NL = LPAD(:4, 2, ''0'')';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnAn, lnLuna;
-- SAL_CALENDAR
ldDataI := TO_DATE(lpad(lnAn, 4, '0') || lpad(lnLuna, 2, '0'), 'YYYYMM');
ldDataF := ADD_MONTHS(ldDataI, 1) - 1;
lcSql := 'select ' || lcSchemaDestinatie ||
'.pack_personal.calculeaza_nr_zile(:1, :2) FROM DUAL';
EXECUTE IMMEDIATE lcSql
INTO lnZileLucratoare
USING ldDataI, ldDataF;
lnOreLucratoare := lnZileLucratoare * 8;
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.SAL_CALENDAR SET AN = :1 , LUNA = :2, ZILELUC = :3, ORESTAS = :4, ORELUC = :5';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnZileLucratoare, lnOreLucratoare, lnOreLucratoare;
-- SAL_IMPOZITAR
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.SAL_IMPOZITAR SET AN = :1 , LUNA = :2';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna;
-- PLCONT
lcSql := 'SELECT max(an) as plan from ' || lcSchemaDestinatie ||
'.PLCONT';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
into lnMaxAn;
if lnMaxAn <> lnAn then
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.PLCONT SET AN = :1 WHERE AN = :2';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnMaxAn;
end if;
-- COTE_TVA
lcSql := 'SELECT max(an*12+luna) from ' || lcSchemaDestinatie ||
'.cote_tva';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
into lnMaxAn;
lcSql := 'UPDATE ' || lcSchemaDestinatie ||
'.COTE_TVA SET AN = :1, LUNA = :2 WHERE AN*12+LUNA = :3';
PINFO(lcSql, lcLocatie);
EXECUTE IMMEDIATE lcSql
USING lnAn, lnLuna, lnMaxAn;
------------------------------------------------------------------------
-- 2. ACTUALIZARE SCHEMA LA ZI
PINFO('Actualizare schema la zi...', lcLocatie);
CONTAFIN_ORACLE.PACK_UPDATE.UpdateROA(tnUpdateApp => 0,
tnUpdateScripturi => 0,
tnUpdateDatabase => 1,
tcSchemaList => tcSchema);
EXCEPTION
WHEN OTHERS THEN
PINFO(SQLERRM, lcLocatie);
raise_application_error(-20000, SQLERRM);
END;
DBMS_DATAPUMP.DETACH(h1);
end NewSchema;
/
CREATE OR REPLACE PROCEDURE SYS.NEWSCHEMAJOB(tcSchema varchar2,
tnLuna number,
tnAn number) as
lcJobName varchar2(500);
begin
lcJobName := 'NEWSCHEMA_' || UPPER(tcSchema);
dbms_scheduler.create_job(job_name => lcJobName,
job_type => 'STORED_PROCEDURE',
job_action => 'NEWSCHEMA',
number_of_arguments => 3,
enabled => false);
dbms_scheduler.set_job_argument_value(lcJobName, 1, tcSchema);
dbms_scheduler.set_job_argument_value(lcJobName, 2, to_char(tnLuna));
dbms_scheduler.set_job_argument_value(lcJobName, 3, to_char(tnAn));
dbms_scheduler.enable(lcJobName);
end NEWSCHEMAJOB;
/
CREATE OR REPLACE PROCEDURE SYS.UpdateSQLPLUS(tcSqlPlusPath in varchar2,
tcScriptPath in varchar2) as
lcJobName varchar2(500);
begin
lcJobName := 'updateschema_' || to_char(sysdate, 'YYYYMMDDHH24MISS');
dbms_scheduler.create_job(lcJobName,
job_action => tcSqlPlusPath,
number_of_arguments => 2,
job_type => 'executable',
enabled => false);
dbms_scheduler.set_job_argument_value(lcJobName, 1, '/nolog');
dbms_scheduler.set_job_argument_value(lcJobName, 2, '@' || tcScriptPath);
dbms_scheduler.enable(lcJobName);
end;
/
-- ============================================================================
-- SECTION 7: UTL_MAIL
-- ============================================================================
-- UTL_MAIL nu se instaleaza implicit in Oracle 21c. Fara el raman INVALID:
-- CONTAFIN_ORACLE.SENDEMAIL, EMAILINCASARI, EMAILNOTIFICAREFACTURI,
-- EMAILSTOCCRITIC, PACK_UPDATE si PACK_UTILS (PLS-00201: UTL_MAIL.SEND).
-- Un GRANT nu ajuta - pachetul trebuie creat. Pe ROA_CENTRAL (productie)
-- UTL_MAIL este VALID; verificat 2026-08-25.
--
-- Grantul catre CONTAFIN_ORACLE se face in sql\sys-grants.sql, dupa import.
-- Pentru trimiterea efectiva de mailuri mai trebuie setat SMTP_OUT_SERVER.
-- ============================================================================
PROMPT
PROMPT [10/10] Installing UTL_MAIL...
@?/rdbms/admin/utlmail.sql
@?/rdbms/admin/prvtmail.plb
PROMPT UTL_MAIL installed.
-- ============================================================================
-- VERIFICATION
-- ============================================================================
PROMPT
PROMPT ========================================
PROMPT Verifying SYS Custom Objects
PROMPT ========================================
PROMPT
PROMPT SYS custom objects status:
SELECT object_name, object_type, status
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN (
'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS',
'PINFO', 'INFO', 'SEQ_AUTH_SERII'
)
ORDER BY object_type, object_name;
PROMPT
PROMPT Invalid objects (should be empty):
SELECT object_name, object_type, status
FROM dba_objects
WHERE owner = 'SYS'
AND object_name IN (
'AUTH_PACK', 'AUTH_DETALII', 'AUTH_SERII', 'VAUTH_SERII',
'EXECUTESCRIPTOS', 'NEWSCHEMA', 'NEWSCHEMAJOB', 'UPDATESQLPLUS',
'PINFO', 'INFO', 'SEQ_AUTH_SERII'
)
AND status != 'VALID';
PROMPT
PROMPT ========================================
PROMPT SYS Custom Objects Installation Complete
PROMPT ========================================
PROMPT