SAP SQL Anywhere - Das Blog

Das deutschsprachige Blog rund um SAP SQL Anywhere

Eine Archivsicherung sichert die komplette Datenbank in eine oder mehrere – abhängig von der Größe der Datenbank – Dateien, die alle erforderlichen Sicherungs- und Wiederherstellungsinformationen enthalten.

Wichtig: alle angegebenen Pfade gelten aus Sicht des Datenbank-Servers, nicht des Clients!

Archivsicherung per iSQL

BACKUP DATABASE TO 'D:\\TEMP\\SQLA\\Archivsicherung\\database_backup'

Die Sicherung erfolgt ins Verzeichnis D:\TEMP\SQLA\Archivsicherung. Dabei ist database_backup der Basisname der Sicherungsdateien. Die erste Datei heißt database_backup.1. Abhängig von der Größe der gesicherten Datenbank entstehen weitere Dateien mit den Dateiendungen “.2”, “.3”, “.4”, usw.

Wiederherstellen aus einer Archivsicherung

Die Wiederherstellung einer Datenbank aus einer Archivsicherung kann entweder über iSQL erfolgen oder über den Wiederherstellungs-Assistenten in SQL Central (früher: “Sybase Central”).

Wiederherstellen über iSQL

RESTORE DATABASE 'D:\\NeueDatenbank\\datenbankdatei.db'
FROM 'D:\\TEMP\\SQLA\\Archivsicherung';

Beim Wiederherstellen gibt man den Pfad zu der neuen Datenbankdatei an (die erzeugt werden soll). Als Quelle für die Wiederherstellung wird jetzt (im Unterschied zum Sichern) nur noch der Name des Sicherungsverzeichnisses angegeben.

Mehr dazu auf Technotes.

#Admin #Backup

Innerhalb eines laufenden SQL Anywhere-Servers existieren eine Vielzahl von sog. globalen Variablen. Die Inhalte werden vom Datenbank-Server gesetzt und können vom Nutzer (oder Entwickler) ausgelesen werden.

Die SQL Anywhere-Dokumentation listet und erklärt diese globalen Variablen vollständig und ausführlich. Hier nur eine kurze Auswahl an einigen interessanten Variablen:

Variable Bedeutung
@@rowcount Anzahl an betroffenen Datensätzen des letzten INSERT-, UPDATE- oder DELETE-Statements
@@version Version des Datenbank-Servers

Siehe auch

Die globale Variable @@rowcount gibt die Anzahl an betroffenen Datensätzen bei einem INSERT-, UPDATE- oder DELETE-Statement zurück.

Nachdem das Statement ausgeführt worden ist, steht die Anzahl in der Variable zur Verfügung und kann z.B. in einer Prozedur ausgelesen werden.

 SELECT @@rowcount

#SQL

Das Umbenennen einer Tabelle ist einfach:

ALTER TABLE old_table_name RENAME new_table_name;

Wann besteht überhaupt sinnvoll der Bedarf, in einer Datenbank-Anwendung eine Tabelle umzubenennen? Ich nutze das immer dann, wenn ich eine Tabelle, die über die Jahre gewachsen ist, reorganisieren will. Dabei soll sich dann vielleicht die Reihenfolge der Spalten ändern oder einzelne Spalten sollen andere Namen bekommen.

Reorganisieren einer Tabelle

Zu beachten ist, dass man ja in der ursprünglichen Tabelle bestehende Datensätze hat, die erhalten bleiben sollen.

Schritte:

  1. bestehende Tabelle umbenennen
  2. neue Tabelle unter dem ursprünglichen Namen anlegen (mit der neuen, überarbeiteten Tabellenstruktur)
  3. die Datensätze aus der alten (umbenannten) Tabelle in die neue Tabelle importieren
  4. die alte (umbenannte) Tabelle löschen

Zu Schritt 3:

Wenn wir davon ausgehen, dass neue Spalten hinzugekommen sind, kann es sein, dass man beim Transfer der Datensätze aus der alten in die neue Tabelle diese neuen Spalten just-in-time berechnen muss.

Ein komplettes Beispiel

Am Beispiel einer Kundentabelle mit folgender Struktur:

  • ID – INTEGER DEFAULT AUTOINCREMENT
  • KUNDENKLASSE – CHAR(1)
  • KUNDENNAME – VARCHAR(30)

Wir wollen folgende Änderungen durchführen:

  • das Feld KUNDENNAME soll in NAME umbenannt werden
  • außerdem reicht uns der Platz für längere Kundennamen nicht – wir wollen das Feld auf 100 Zeichen verlängern
  • wir wollen die Postleitzahl der Kunden speichern – brauchen dafür also eine neue Spalte PLZ mit 5 Zeichen Platz
  • zu guter Letzt soll das Feld KUNDENKLASSE hinter den Kundennamen rutschen, damit man beim bequemen Abfragen der Tabelle per SQL als erstes ID und Name der Datensätze sieht
  1. Die bisherige Tabelle kunden wird umbenannt nach kunden_tmp.

    -- Tabelle umbenennen
    ALTER TABLE kunden RENAME kunden_tmp;
    
  2. Die neue Tabelle kunden wird mit der geforderten Tabellenstruktur angelegt.

    -- neue Tabelle anlegen
    CREATE TABLE kunden (
    ID                INTEGER DEFAULT AUTOINCREMENT,
    NAME              VARCHAR(100),
    KUNDENKLASSE      CHAR(1),
    PLZ               CHAR(5),
    PRIMARY KEY ( ID )
    );
    
  3. Die Datensätze aus der alten Tabelle in die neue Tabelle übernehmen. Dabei wird hier im SELECT-Statement aus der alten Tabelle die Reihenfolge der ausgelesenen Spalten angepasst, damit sie zur Reihenfolge der Spalten in der neuen Tabelle passt. Das neue Feld PLZ bleibt leer und wird auch nicht angesprochen – wir haben dafür ja noch keine Daten.

    -- Datensätze aus der alten Tabelle übernehmen
    INSERT INTO kunden (id, name, kundenklasse)
    SELECT id, kundenname, kundenklasse
    FROM kunden_tmp;    
    
  4. Die ursprüngliche und jetzt umbenannte Kundentabelle kunden_tmp kann jetzt gelöscht werden.

    -- Tabelle löschen
    DROP TABLE kunden_tmp;
    

#SQL #DDL

Eine Printf-Funktion gibt es in vielen Programmiersprachen. Damit kann man Strings zusammenbauen, die aus fest definierten Bestandteilen sowie dynamischen Variablen bestehen.

Auch in einer SQL Anywhere-Prozedur kann man diese Funktionalität nutzen. Es gibt dazu eine Systemprozedur xp_sprintf.

Wichtig dabei ist, dass diese mit der Zielvariable als ersten Parameter aufgerufen wird. Es handelt sich also nicht um eine Funktion, die einen Wert liefert, den man der Zielvariable zuweisen kann.

DECLARE ls_anrede VARCHAR(100);
DECLARE ls_vorname VARCHAR(50);
DECLARE ls_nachname VARCHAR(50);

SET ls_vorname = 'James';
SET ls_nachname = 'Bond';

CALL xp_sprintf(ls_anrede, 'Hallo %s %s', ls_vorname, ls_nachname);

Dieses Snippet hätte als Ergebnis in der Variable ls_anrede den Wert Hallo James Bond.

Mehr dazu auf Technotes.

#SQL

Im Laufe der Zeit sammeln sich in einer Datenbank-Anwendung immer auch Utility-Funktionen und -Tabellen an. Eine davon, die ich immer wieder hilfreich finde: eine Tabelle, die genau einen Datensatz beinhaltet. Dabei muss sichergestellt werden, dass Nutzer diesen nicht löschen können und auch keine weiteren Datensätze anlegen können.

CREATE TABLE one_row_only (
    one_row_only INTEGER NOT NULL DEFAULT 1 CHECK ( one_row_only = 1 ) PRIMARY KEY,
    started_at TIMESTAMP NOT NULL
);

CREATE TRIGGER tdb_one_row_only BEFORE DELETE ON one_row_only
FOR EACH ROW
BEGIN
    ROLLBACK TRIGGER WITH RAISERROR 99999 'Do not attempt to delete from one_row_only';
END;

INSERT INTO one_row_only VALUES ( DEFAULT, CURRENT TIMESTAMP );
COMMIT;

Mehr dazu auf Technotes.

#SQL #DDL

Kontaktieren Sie mich bitte über meine Website www.jakoubek.net

Es soll ein Datensatz angelegt werden und gleichzeitig die von der Datenbank vergebene ID des neuen Datensatzes zurückgegeben werden, ohne diese Tabelle abzufragen (und ohne Krücke wie @@IDENTITY).

SELECT new_rec.id
FROM (
    INSERT INTO your_table_name ( description )
    VALUES ( 'new record' )
) REFERENCING ( FINAL AS new_rec );

#SQL

Per SQL hat man natürlich die Möglichkeit, bei einer bereits bestehenden Spalte in einer Tabelle nachträglich noch die DEFAULT-Wert zu ändern oder überhaupt erst zu setzen:

ALTER TABLE table_name MODIFY column_name DEFAULT 1;

Auf die bereits existierenden Datensätze wirkt sich das nicht aus.

#SQL #DDL

Oft besteht der Bedarf, in einer Tabelle Zeitpunkt der Anlage eines Datensatzes sowie der letzten Änderung identifizieren zu können. Der einfachste Weg ist, in einer Tabelle zwei Timestamp-Spalten anzulegen, eine für den Anlagezeitpunkt und einen für die letzte Änderung.

Über den Default-Wert einer Spalte lässt sich automatisch der Anlagezeitpunkt in den Datensatz schreiben.

Beim Zeitpunkt der letzten Änderung ist das etwas schwieriger – dafür muss man zu einem Trigger greifen.

Tabelle anlegen

CREATE TABLE table_name (
  id           INTEGER AUTOINCREMENT,
  description  VARCHAR(100) NOT NULL,
  created_at   DATETIME DEFAULT CURRENT TIMESTAMP
  updated_at   DATETIME
);

Die Spalte created_at wird durch die Angabe eines DEFAULT-Wertes (nur!) beim Anlegen eines Datensatzes auf den jeweiligen jetzigen Zeitpunkt gesetzt. Die Spalte updated_at bleibt erst einmal leer.

Trigger anlegen

CREATE TRIGGER tub_TABLE_NAME_TS
BEFORE UPDATE ORDER 1
ON table_name
REFERENCING NEW AS newrec
FOR EACH ROW
BEGIN
  SET newrec.updated_at = CURRENT TIMESTAMP;
END;

Dieser Trigger wird beim Ändern eines Datensatzes gefeuert (genauer: vor dem Festschreiben der Änderung) und setzt die Spalte updated_at auf den jetzigen Zeitpunkt.

Mehr dazu auf Technotes.

#SQL #DDL #Trigger

Enter your email to subscribe to updates.