Signatur
Beschreibung
sqlsrv_prepare() kompiliert eine SQL-Anweisung auf dem SQL Server und gibt eine Statement-Ressource zurück, die anschließend beliebig oft mit sqlsrv_execute() ausgeführt werden kann. Dies ist besonders effizient, wenn dieselbe Abfrage mit wechselnden Parameterwerten wiederholt werden soll, da die Abfrage nur einmal geparst und optimiert wird.
Parameter werden als Platzhalter (?) in der SQL-Anweisung angegeben und über das $params-Array gebunden. Jedes Element kann entweder eine einfache PHP-Variable oder ein Array der Form [$variable, $direction, $phpType, $sqlType] sein. Da die Variablen per Referenz gebunden werden, spiegeln sich nachträgliche Änderungen an den PHP-Variablen bei der nächsten Ausführung automatisch wider.
Im Gegensatz zu sqlsrv_query(), das die Anweisung vorbereitet und sofort ausführt, trennt sqlsrv_prepare() diese beiden Schritte und eignet sich daher ideal für Batch-Inserts oder wiederholte Datenbankoperationen in Schleifen.
Über das optionale $options-Array lassen sich Abfrageeigenschaften wie Scrollable Cursor oder Query Timeout steuern.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $conn Pflicht | resource | Eine aktive Verbindungsressource, die von sqlsrv_connect() zurückgegeben wurde. |
|
| $sql Pflicht | string | Die SQL-Anweisung als Zeichenkette. Parameterpositionen werden mit ?-Platzhaltern markiert. |
|
| $params | array | [] | Ein optionales Array mit den an die Platzhalter gebundenen PHP-Variablen. Jeder Eintrag ist entweder eine Variable (per Referenz gebunden) oder ein Array [$var, $direction, $phpType, $sqlType], wobei $direction z. B. SQLSRV_PARAM_IN oder SQLSRV_PARAM_OUT sein kann. |
| $options | array | [] | Ein optionales assoziatives Array mit Abfrageoptionen, z. B. 'Scrollable', 'QueryTimeout' oder 'SendStreamParamsAtExec'. |
Rückgabewert
sqlsrv_execute() ausgeführt werden kann, oder false bei einem Fehler. Fehlerdetails können mit sqlsrv_errors() abgerufen werden.Beispiele
Wiederholte INSERT-Anweisung mit wechselnden Parametern
<?php
$conn = sqlsrv_connect('localhost', [
'Database' => 'TestDB',
'UID' => 'sa',
'PWD' => 'geheim'
]);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
$sql = "INSERT INTO Produkte (Name, Preis) VALUES (?, ?)";
$name = '';
$preis = 0.0;
$stmt = sqlsrv_prepare($conn, $sql, [&$name, &$preis]);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
$produkte = [
['Apfel', 0.49],
['Banane', 0.39],
['Kirsche', 1.29],
];
foreach ($produkte as [$n, $p]) {
$name = $n;
$preis = $p;
if (sqlsrv_execute($stmt) === false) {
echo "Fehler bei '$name': " . print_r(sqlsrv_errors(), true);
} else {
echo "Eingefügt: $name ($preis EUR)\n";
}
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
SELECT-Abfrage mit Eingabeparameter und Ergebnisabruf
<?php
$conn = sqlsrv_connect('localhost', [
'Database' => 'TestDB',
'UID' => 'sa',
'PWD' => 'geheim'
]);
$kategorie = 'Obst';
$sql = "SELECT Name, Preis FROM Produkte WHERE Kategorie = ?";
$stmt = sqlsrv_prepare($conn, $sql, [&$kategorie]);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
if (sqlsrv_execute($stmt)) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
echo $row['Name'] . ': ' . $row['Preis'] . " EUR\n";
}
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
// Wichtig · Fallstricke
Sicherheit: Durch die Verwendung von ?-Platzhaltern und gebundenen Parametern werden SQL-Injection-Angriffe zuverlässig verhindert. Niemals Benutzereingaben direkt in die SQL-Zeichenkette einbetten.
Referenzbindung: Die Parameter werden per Referenz (&$variable) übergeben. Das bedeutet, dass der Wert der Variable zum Zeitpunkt von sqlsrv_execute() gelesen wird, nicht bereits bei sqlsrv_prepare().
Ressourcenverwaltung: Nach der Verwendung sollte die Statement-Ressource mit sqlsrv_free_stmt() freigegeben werden, um Speicher zu sparen, besonders in Schleifen oder bei langen Skriptlaufzeiten.
Treiber: Diese Funktion gehört zum SQLSRV-Treiber von Microsoft (php_sqlsrv) und ist nicht Teil des PDO- oder MySQLi-Stacks. Alternativ kann der PDO_SQLSRV-Treiber mit PDO::prepare() genutzt werden.