User Tools

Site Tools


php:tutorials:sqlreadable

[PHP] SQL-Statement in PHP lesbar darstellen

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.

Ausgangslage

Ich nehme mal das folgende SQL-Statement um die erste freie ID zu ermitteln

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 Forum gesehen habe, würde dass dann so aussehen

$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;");

Na, viel vergnügen beim lesen.

Lösung

1) 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

$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 Zeileunmbrüche und Tabulatoren in den SQL-Code einfügen. Dazu eignet sich die Heredoc-Syntax hervorragend

$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);

2) 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

$myMinNumber = $_POST['myMinNumber'];
//TODO: $myMinNumber auf gültigkeit prüfen
 
$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

$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);

3) 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

-- 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;

Auszug aus der PHP-Datei

$myMinNumber = $_POST['myMinNumber'];
//TODO: $myMinNumber auf gültigkeit prüfen 
 
$sql = sprintf(file_get_contents('/queries/first_not_used_id.sql'), $myMinNumber);
$result=mysql_query($sql);
php/tutorials/sqlreadable.txt · Last modified: 26.03.2015 11:42:58 by yaslaw