Archiv der Kategorie: SQL

Datenbank-Trigger zur Fehlersuche

Bei Fremdanwendungen mit unzugänglichem Code oder auch für ein schnelles Eingrenzen von Fehlern unbekannter Herkunft kann unter Zuhilfenahme einiger, neuerer Trigger-Features ganz bequem mit einem autonomen Schema- oder Database-Trigger ein Logging ausgelöst werden. Der folgende Code protokolliert einen Fehler mit seinem Errorstack und dem zugehörigen SQL und kann damit auch zum Logging von SQL-Exceptions genutzt werden:

DROP TABLE servererror_log
/
CREATE TABLE servererror_log (
  error_datetime TIMESTAMP,
, error_user VARCHAR2(30)
, error_stack VARCHAR2(2000)
, error_backtrace VARCHAR2(4000)
, captured_sql VARCHAR2(4000))
/
CREATE OR REPLACE
TRIGGER log_server_errors
AFTER SERVERERROR
ON SCHEMA -- oder auch "ON DATABASE"
DECLARE
  PRAGMA autonomous_transaction;
  sql_text DBMS_STANDARD.ora_name_list_t;
  n PLS_INTEGER;
  v_stmt VARCHAR2(4000);
BEGIN
  -- Das problematische SQL...
  n := ora_sql_txt(sql_text);
  -- ... besteht ggf. aus mehreren Teilen und wird in einer Schleife wieder zusammengefügt
  FOR i IN 1..n LOOP
    v_stmt := v_stmt || sql_text(i);
  END LOOP;

  INSERT INTO servererror_log
   ( error_datetime
   , error_user
   , error_stack
   , error_backtrace
   , captured_sql )
  VALUES
   ( systimestamp
   , sys.login_user
   , dbms_utility.format_error_stack
   , dbms_utility.format_error_backtrace
   , v_stmt );
  COMMIT;
END log_server_errors;
/
Anmerkung: Dieser Beispielcode ist nicht für den Einsatz in produktiven Umgebungen konzipiert worden!

Hier noch ein paar Links zu den im Beispiel benutzten Features:

Werbeanzeigen

Unterbewertet oder unbekannt: Deferred Constraints

Über Nutzen und Nachteile von Constraints wird gerne und leidenschaftlich gestritten. Auf der Seite der Nachteile wird oft angeführt, daß die zeilenweise Verifizierung (im Englischen auch gerne als „slow-by-slow“ verballhornt) ein Performance-Killer ist. Es wäre also durchaus praktisch, wenn auch Constraints stapelweise, z.B. pro Transaktion, abgearbeitet werden könnten. Auftritt der Deferred Constraints!

Weiterlesen

NVL-st Du noch oder COALESCE-t Du schon?

NULL-„Werte“ an sich können dem DB-Entwickler genug Kopfzerbrechen bereiten, um alleine damit ganze Artikelserien zu füllen. Hier möchte ich mich lediglich auf einen kleinen Ausschnitt der Problematik beschränken, nämlich der Performance beim Vergleichen und Ersetzen von NULLs. Zum Ersetzen von NULLs in Abfragen wird zumeist die Funktion NVL() verwendet. Diese Funktion hat jedoch zwei entscheidende Nachteile:

  1. Sie bietet nur die Möglichkeit, genau einen Ausdruck mit einem anderen zu ersetzen. Will man mehr als zwei Ausdrücke gegeneinander vergleichen, muss die Funktion kaskadiert werden.

  2. Der zweite Ausdruck wird immer ausgewertet, auch dann, wenn der erste Ausdruck bereits NOT NULL ist.

Weiterlesen

Lateral SQL Injection: Neue Erkenntnisse

SQL Injection ist ein Verfahren, über eine Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbankbefehle einzuschleusen. Jeder Entwickler, der sicherheitsrelevante DB-Anwendungen schreibt und dabei dynamisch generiertes SQL einsetzt, sollte mit diesem Angriffsszenario und den Gegenmaßnahmen vertraut sein.

David Litchfield von databasesecurity.com hat bereits 2008 eine spezielle Form von SQL Injection in Oracle demonstriert, die er „Lateral Injection“ nannte. Das Verfahren hat es ermöglicht, in PL/SQL-Prozeduren trotz korrekt typisierter Parameter mit Hilfe von NLS_DATE_FORMAT schadhaften Code in dynamisches SQL einzuschleusen. Diese Woche nun wies er auf ein neues Whitepaper hin, das aufzeigt, daß auch NUMBER-Parameter mit Hilfe von NLS_NUMERIC_CHARACTERS dergestalt manipuliert werden können, daß die Ausführung fremder Funktionen möglich wird. Weiterlesen

DOAG2011 – Addenda

Sodele, eine interessante DOAG-Konferenz liegt hinter mir, und in der Nachbetrachtung meines Vortrages „Oracle Old Features“ ist mir aufgefallen, daß in den Unterlagen die Quellen- und Literaturhinweise fehlten. Diese möchte ich hier nachliefern, und zwar umfangreicher als geplant.
Wer nicht auf der Konferenz war und daher auch nicht die Vortragsunterlagen herunterladen kann: Nicht traurig sein, ich werde in diesem Blog noch einiges über wichtige, oft unterbewertete „Old Features“ veröffentlichen!

Constraints

Fremdschlüssel, Query Rewrite

RELY-Constraints

  • RELY wieder entfernen, bevor „enable validate“ durchgeführt wird! Siehe hier.

Deferred Constraints

COALESCE, ANSI-Joins, WITH-Clause etc.

SQL*Plus, AUTOCOMMIT und EXIT

Auch wenn das eigentlich ein Grundlagenthema sein sollte — gerade heute durfte ich selbst mal wieder erfahren, daß es folgenreiche Unterschiede zwischen dem kontrollierten Abbruch eines Skriptes in SQL*Plus und dem Abbruch einer Server-seitigen Session gibt.

Mythos: Ein „quit“ oder ein „whenever sqlerror exit“ bewirken ein Rollback beim Beenden eines Skriptes.

Tatsache: Ein „exit“ in SQL*Plus impliziert ein COMMIT und kein ROLLBACK!

Weiterlesen