Files
gala-ki-spielwiese/CLAUDE.md

7.7 KiB

CLAUDE.md — Oracle Database

Projektbeschreibung

Projekt für verschiedene Oracle-Datenbank Entwicklungen. Enthält Tabellendefinitionen, PL/SQL-Packages, ORDS-Endpunkte, Views, Trigger etc.

SQL / PL/SQL Guidelines

Formatierung

Keywords immer klein:

select, from, where, insert into, create table, begin, end, exception, ...

Tab-Ausrichtung in mehrzeiligen Statements:

Schlüsselwort + Tab, dann Inhalt. Erste Spalte und alle nachfolgenden Kommas stehen auf demselben Tab-Stop (eine Fluchtlinie). Komma direkt vor dem Spaltennamen ohne Leerzeichen.

select	order_id
		,principal_order_number
		,total_amount
from	fgt_order
where	status = 'COMPLETE'
insert into	fgt_order (
		order_id
		,principal_order_number
		,total_amount
) values (
		fgt_order_seq.nextval
		,p_order_number
		,p_total_amount
);

Block-Keywords in eigener Zeile (lineup bracing):

loop, then, exception und ihre schließenden end-Varianten stehen auf gleicher Einrückungsebene wie der Block-Öffner:

for rec in cur_open_orders
loop
    l_count := l_count + 1;
end loop;

if l_count > 0
then
    do_something();
elsif l_count < 0
then
    handle_negative();
end if;

begin
    l_result := do_something();
exception
    when e_not_found
    then
        l_result := null;
    when others
    then
        raise;
end;

end-Anweisungen immer mit Label:

end my_procedure;
end my_package;

Indentation: 4 Spaces innerhalb von Blöcken.


Benennungskonventionen

Objekt Konvention Beispiel
Tabellen Modulabhängiger Präfix, z.B.adr_, Singular, Dateiendung .tab sy_parameter, adr_adresse_zuweisung,
Views v_ Präfix v_adr_adresse_zuweisung
Packages pck_ Präfix, Separate header und body Dateien mit den Endungen .pkh und .pkb pck_system
Prozeduren p_-Präfix p_insert_order, p_delete_folder
Funktionen f_-Präfix f_get_order, f_build_url
Lokale Variablen l_-Präfix l_order_id, l_count
Parameter (Input) i_-Präfix i_json, i_order_id
Package-globale Variablen g_-Präfix g_default_currency
Konstanten c_-Präfix c_max_retries
Cursor cur_-Präfix cur_open_orders
Exceptions e_-Präfix e_not_found, e_duplicate
Views _v-Suffix fgt_order_v
Trigger trg_-Präfix trg_fgt_order_created_at
Sequences <zweck>_seq fgt_order_id_seq
Primary Key (Spalte) <tabellenname>_id order_id, shipment_id
Foreign Key (Constraint) <beschreibung>_fk fgt_order_bill_addr_fk

PL/SQL-Struktur

  • as für Package-Spec/Body-Header, is für Prozedur-/Funktionskörper innerhalb eines Packages
  • Implizite Cursor-FOR-Loops bevorzugen gegenüber expliziten Cursors
  • is null / is not null verwenden — niemals = null / != null
  • Explizite Formatmasken in to_date, to_char, to_timestamp
  • commit nur im äußersten Aufrufer — nie in Sub-Prozeduren
create or replace package body pck_orders as

    procedure insert_order (i_json in clob, i_run_id in varchar2)
    is
        l_order_id    number;
        l_status      varchar2(20);
    begin
        -- Implementierung
        l_order_id := bet_order_id_seq.nextval;
    end insert_order;

end fgt_orders;

Exception Handling

  • Niemals when others then null — Exceptions nie stillschweigend schlucken
  • Exceptions mit e_-Präfix benennen und im Deklarationsteil definieren
  • sqlerrm und sqlcode für Fehlerinformationen nutzen
declare
    e_invalid_status    exception;
    l_status            varchar2(20);
begin
    if l_status not in ('COMPLETE', 'INCOMPLETE')
    then
        raise e_invalid_status;
    end if;
exception
when e_invalid_status
then
    -- gezielt behandeln
    log_error('Ungültiger Status: ' || l_status);
when others
then
    -- sqlcode / sqlerrm immer loggen, nie schlucken
    log_error(sqlerrm);
    raise;
end;

Audit-Spalten

Jede Tabelle bekommt am Ende vier Audit-Spalten:

create table bet_order (
    bet_order_id          number generated by default as identity not null enable
    , ...
    ,bet_mit_id_angelegt     NUMBER(10) not null,
  	,bet_datum_angelegt      DATE not null,
  	,bet_mit_id_geaendert    NUMBER(10) not null,
 	,bet_datum_geaendert     DATE not null,
);

Befüllt werden sie über einen before insert or update-Trigger pro Tabelle. Namenskonvention: trg_<tabellenname>_audit.

create or replace editionable trigger trg_fgt_order_audit
before
    insert or update on fgt_order
    referencing
        new as new
        old as old
    for each row
declare
    l_user      varchar2(100 byte) := substr(upper(coalesce(
                    sys_context('apex$session', 'app_user'),
                    sys_context('userenv', 'os_user'),
                    sys_context('userenv', 'session_user'))), 1, 100);
    l_now       date := cast(current_timestamp at time zone 'Europe/Berlin' as date);
begin
    if inserting
    then
        :new.created_at := l_now;
        :new.created_by := l_user;
    end if;
    :new.changed_at := l_now;
    :new.changed_by := l_user;
end trg_fgt_order_audit;

Der Benutzername wird bevorzugt aus der APEX-Session gelesen, mit Fallback auf OS- bzw. DB-Session-User.


Tabellenänderungen (Migrations-Skripte)

Tabellen können von SQLcl Projects nicht gedropt und neu erstellt werden, wenn sie Daten enthalten. Änderungen an bestehenden Tabellen werden deshalb als alter table-Statements am Ende der jeweiligen Tabellendatei ergänzt — nach dem create table und dem Primary-Key-Constraint, aber vor dem -- sqlcl_snapshot-Kommentar.

So kann die gesamte Datei als Skript auf eine bestehende Datenbank angewendet werden: Das create table schlägt fehl (Tabelle existiert schon), aber die alter table-Statements laufen durch und bringen die Tabelle auf den aktuellen Stand.

create table fgt_order ( ... );

alter table fgt_order
    add constraint pk_fgt_order primary key (order_id)
        using index enable;

-- Migrationsscript — hinzugefügt am 2026-03-30
alter table fgt_order add (
     status  varchar2(16 char)  default 'COMPLETE' not null
    ,run_id  varchar2(36 char)
);

-- sqlcl_snapshot { ... }

Planungsdokumente

Für komplexere Features/Packages wird ein Planungsdokument als .md-Datei im Projektverzeichnis abgelegt (z.B. plan_pck_net_storage.md). Der Plan wird während der Umsetzung aktuell gehalten — jede Änderung an Architektur oder Schnittstelle wird sofort im Plan nachgeführt.


Kommentare

  • Beschreibungen auf Deutsch, Code (außer Fachbegriffe der Anwendungsdomäne) auf Englisch
  • Block-Kommentar zu Beginn Prozedur/Funktion mit Zweck und Parametern
  • Inline-Kommentare mit -- nur für nicht-offensichtliche Logik
procedure insert_order (i_json in clob, i_run_id in varchar2) 
  /*Kopf------------------------------------------------------------------------------------------------
  -- Beschreibung:  Fügt einen verarbeiteten Auftrag in die Datenbank ein.
  ------------------------------------------------------------------------------------------------------
  -- Parameter: i_json   	Klippa-Ergebnis als JSON-String
  --            i_run_id	Ausführungs-Korrelations-ID des Verarbeitungslaufs
  ------------------------------------------------------------------------------------------------------
  -- Rückgabe:  <nur bei funktionen, nicht bei procedures>
  ------------------------------------------------------------------------------------------------------
  -- MA   Datum       Änderung
  -- SCK  2026-04-07  Funktion erstellt
  ------------------------------------------------------------------------------------------------Kopf*/ 
is
...