Einleitung
In dieser kleinen Anleitung will ich zeigen, dass auch SQL-Befehle nicht immer als lange und unübersichtliche Strings im PHP-Code verwendet werden müssen.
Grundsätzlich wissen wir, das unsauber formatierter Code zwar von der Maschine intepretiert werden kann, jedoch für den Programmierer nicht immer lesbar sind. So schleichen sich Fehler ein die man nur schwer findet. Eine offene Klammer die nie geschlossen wird ist der typische Fall.
Auch bei SQL-Statements kann dies geschehen.
Ich nehme mal das folgende SQL-Statement um die erste freie ID zu ermitteln
Bei den meisten PHP-Codes die ich hier im Foruim gesehen habe, würde dass dann so aussehen
Na, viel vergnügen beim lesen.
SQL auf mehrere Zeilen verteilen
Also, ran ans formatieren.
Zuerst trenne ich mal den mysql_query() Befehl vom String. Ich setze also den String in eine Variable
Naja, viel lesbarer ists noch nicht. Also ran an den Code und Zeilenumbrüche und Tabulatoren in den SQL-Code. Dazu eignet sich die Heredoc-Syntax hervorragend
Mit Variablen im SQL-Statement
Und wenn wir da jetzt noch Variabeln mit einbauen müssen, haben wir viele Varianten. Die Prepared-SQL-Statement-Methode lasse ich jetzt mal aus und gehe den rein prozedualen Weg.
Um das zu demonstrieren erweitere ich mein Code um die Zeile 'HAVING MIN(newIds.newId) > $myMinNumber' um ein Minimum zu defineren.
1. Möglichkeit: Direkt in den String setzen
Dazu eignet sich die Complex (Curly) Syntax von PHP
2. Möglichkeit: printf()
Das ist sehr praktisch wenn man den Wert nicht direkt als Variabel hat, sondern als Resultat einer Funktion kriegt
Grosse SQL-Statements auslagern
Bei wirklich grossen SQL-Statements lohnt es sich ggf das ganze in ein .sql-File auszulagern und mit file_get_contents() einzulesen
Datei first_not_used_id.sql im Unterverzeichnis queries
Auszug aus der PHP-Datei
In dieser kleinen Anleitung will ich zeigen, dass auch SQL-Befehle nicht immer als lange und unübersichtliche Strings im PHP-Code verwendet werden müssen.
Grundsätzlich wissen wir, das unsauber formatierter Code zwar von der Maschine intepretiert werden kann, jedoch für den Programmierer nicht immer lesbar sind. So schleichen sich Fehler ein die man nur schwer findet. Eine offene Klammer die nie geschlossen wird ist der typische Fall.
Auch bei SQL-Statements kann dies geschehen.
Ich nehme mal das folgende SQL-Statement um die erste freie ID zu ermitteln
SQL:
SELECT
MIN(newIds.newId) AS firstNotUsedId
FROM
-- jeweils die nächst höhere ID ermitteln
(SELECT id + 1 AS newId FROM test) AS newIds
-- und mit der Tabelle zurückverknüpfen
LEFT JOIN (SELECT id FROM test ) AS ids
ON newIds.newId = ids.id
WHERE
ids.id IS NULL;
Bei den meisten PHP-Codes die ich hier im Foruim gesehen habe, würde dass dann so aussehen
PHP:
$result=mysql_query("SELECT MIN(newIds.newId) AS firstNotUsedId FROM (SELECT id + 1 AS newId FROM test) AS newIds LEFT JOIN (SELECT id FROM test ) AS ids ON newIds.newId = ids.id WHERE ids.id IS NULL;");
SQL auf mehrere Zeilen verteilen
Also, ran ans formatieren.
Zuerst trenne ich mal den mysql_query() Befehl vom String. Ich setze also den String in eine Variable
PHP:
$sql = "SELECT MIN(newIds.newId) AS firstNotUsedId FROM (SELECT id + 1 AS newId FROM test) AS newIds LEFT JOIN (SELECT id FROM test ) AS ids ON newIds.newId = ids.id WHERE ids.id IS NULL;"
$result=mysql_query($sql);
Naja, viel lesbarer ists noch nicht. Also ran an den Code und Zeilenumbrüche und Tabulatoren in den SQL-Code. Dazu eignet sich die Heredoc-Syntax hervorragend
PHP:
$sql = <<<SQL
SELECT
MIN(newIds.newId) AS firstNotUsedId
FROM
(SELECT id + 1 AS newId FROM test) AS newIds
LEFT JOIN (SELECT id FROM test ) AS ids
ON newIds.newId = ids.id
WHERE
ids.id IS NULL;
SQL;
$result=mysql_query($sql);
Mit Variablen im SQL-Statement
Und wenn wir da jetzt noch Variabeln mit einbauen müssen, haben wir viele Varianten. Die Prepared-SQL-Statement-Methode lasse ich jetzt mal aus und gehe den rein prozedualen Weg.
Um das zu demonstrieren erweitere ich mein Code um die Zeile 'HAVING MIN(newIds.newId) > $myMinNumber' um ein Minimum zu defineren.
1. Möglichkeit: Direkt in den String setzen
Dazu eignet sich die Complex (Curly) Syntax von PHP
PHP:
$myMinNumber = $_POST['myMinNumber'];
//TODO: $myMinNumber auf Gültigkeit prüfen und gg. SQL-Injection absichern!!
$sql = <<<SQL
SELECT
MIN(newIds.newId) AS firstNotUsedId
FROM
(SELECT id + 1 AS newId FROM test) AS newIds
LEFT JOIN (SELECT id FROM test ) AS ids
ON newIds.newId = ids.id
WHERE
ids.id IS NULL
HAVING
MIN(newIds.newId) > {$myMinNumber};
SQL;
$result=mysql_query($sql);
2. Möglichkeit: printf()
Das ist sehr praktisch wenn man den Wert nicht direkt als Variabel hat, sondern als Resultat einer Funktion kriegt
PHP:
$sql = <<<SQL
SELECT
MIN(newIds.newId) AS firstNotUsedId
FROM
(SELECT id + 1 AS newId FROM test) AS newIds
LEFT JOIN (SELECT id FROM test ) AS ids
ON newIds.newId = ids.id
WHERE
ids.id IS NULL
HAVING
MIN(newIds.newId) > %d;
SQL;
$sql = sprintf($sql, getMinNumber('param1'));
$result=mysql_query($sql);
Grosse SQL-Statements auslagern
Bei wirklich grossen SQL-Statements lohnt es sich ggf das ganze in ein .sql-File auszulagern und mit file_get_contents() einzulesen
Datei first_not_used_id.sql im Unterverzeichnis queries
SQL:
-- Parameters:
-- <Number> minNumber
SELECT
MIN(newIds.newId) AS firstNotUsedId
FROM
-- jeweils die nächst höhere ID ermitteln
(SELECT id + 1 AS newId FROM test) AS newIds
-- und mit der Tabelle zurückverknüpfen
LEFT JOIN (SELECT id FROM test ) AS ids
ON newIds.newId = ids.id
WHERE
ids.id IS NULL
HAVING
MIN(newIds.newId) > %d;
PHP:
$myMinNumber = $_POST['myMinNumber'];
//TODO: $myMinNumber auf Gültigkeit prüfen und gg. SQL-Injection absichern!!
$sql = sprintf(file_get_contents('/queries/first_not_used_id.sql'), $myMinNumber);
$result=mysql_query($sql);