Um eine Datenbank auf dem aktuellen Stand zu halten, bietet sich ANT mit dem Task sql an. Hiermit ist es ein leichtes viele SQL-Skripte effektiv in die Datenbank einzuspielen:
<sql driver="org.database.jdbcDriver" url="jdbc:database-url" userid="sa" password="pass" src="data.sql"/> |
Der Lösung so nah
Dies funktioniert soweit sehr gut, es sei denn man versucht Funktionen in die Datenbank einzuspielen. ANT kann leider nicht mit den Semikoli (;) in der Funktion richtig umgehen; so wird davon ausgegegangen das jedes Semikolon ein Statement beendet. Dies trifft beim Einspielen einer Funktion natürlich nicht zu. Hierfür bietet ANT eine schnelle Lösung mit dem Attribute “delimiter” am sql-Task. In dem folgenden Beispiel wird der Default-Delimiter (;) durch “$$” ersetzt.
<sql driver="org.database.jdbcDriver" url="jdbc:database-url" userid="sa" password="pass" src="data.sql" delimiter="$$"/> |
Einfacher Fall
Das SQL der einzuspielenden Funktion für PostgreSQL sollte in etwa wie folgt aussehen:
CREATE OR REPLACE FUNCTION hello_world() RETURNS void AS ' BEGIN -- Aktionen der Funktion END; ' LANGUAGE 'plpgsql' $$ |
Das SQL-Statement erstellt eine Funktion ohne Rückgabewerte, definiert danach die verwendete Sprache und beschliesst das Statement mit dem Delimiter ($$).
Ein kleines aber sehr wichtiges Detail sind hierbei die Hochkomma (‘) hinter dem AS und vor dem LANGUAGE. Auch wenn bei der Verwendung von PgAdmin fast jede beliebiege Zeichenkette dort stehen kann sollte bei der Verwendung von ANT nur das Hochkomma verwendet werden, so das der JDBC den Inhalt der Funktion als Text auffasst und nicht versucht den Inhalt zu interpretieren.
Komplexer Fall
Doch was tun, wenn innerhalb der Funktion Texte verwendet werden, die selbst mit einem Hochkomma (‘) eingefasst sind. In diesem Fall muss man darauf achten, das alle Hochkommas innerhalb der Funktion mit einem Hochkomma “escaped” werden.
CREATE OR REPLACE FUNCTION hello_world() RETURNS void AS ' BEGIN insert into my_table (text) values (''hello''); END; ' LANGUAGE 'plpgsql' $$ |