2015-07-22 31 views
6

Przejrzałem kilka innych pytań, które wydają się (z tytułów) takie same jak te. Jednak mój przypadek jest trochę inny.Jak wykonać procedurę przechowywaną w php za pomocą sqlsrv i "?" parametry stylu

następujące prace (czyli uzyskać „sukces” i moja baza danych wykonuje czego można oczekiwać po uruchomieniu procedury z podanych zmiennych):

$sql = "MyDB.dbo.myProcedure {$var1}, {$var2}, {$var3}"; 
$result = sqlsrv_query($myConn, $sql); 
if (!$result) { 
    echo 'Your code is fail.'; 
} 
else { 
    echo 'Success!'; 
} 

chcę uniknąć (lub zmniejszyć możliwość) SQL iniekcję poprzez utworzenie ciągu SQL przy użyciu parametrów. Na przykład:

$sql = "select * from aTable where col1 = ? AND col2 = ?"; 
$result = sqlsrv_query($myConn, $sql, array($var1, $var2)); 
//please note. This code WILL work! 

Ale gdy robię to z procedura składowana, nie powiedzie się. Nie powiedzie się, nie zgłoszono błędów za pośrednictwem sqlsrv_errors(), nie podjęto żadnych działań w bazie danych i $result === false.

Aby być jasne, po awarii:

$sql = "MyDB.dbo.myProcedure ?, ?, ?"; 
$result = sqlsrv_query($myConn, $sql, array($var1, $var2, $var3)); 

Tak samo przygotować/wykonać rachunek utworzony w ten sam sposób nie powiedzie się także:

$sql = "MyDB.dbo.myProcedure ?, ?, ?"; 
$stmt = sqlsrv_prepare($myConn, $sql, array(&$var1, &$var2, &$var3)); 
foreach($someArray as $key => $var3) { 
    if(sqlsrv_execute($stmt) === false) { 
     echo 'mucho fail.'; 
    } 
} 
//this code also fails. 

Dla kompletności, I potwierdziły, że procedura przechowywana pod tym względem działa bezpośrednio w SQL Management Studio ORAZ jeśli jest tak nazywany w powyższy sposób. Podobnie, potwierdziłem, że I może użyć sparametryzowanych zapytań dla każdego surowego zapytania (jak wstawka, wybierz, aktualizacja vs procedura przechowywana).

Moje pytanie brzmi: jak wywołać procedurę przechowywaną za pomocą sparametryzowanego zapytania zamiast osadzania zmiennych w ciągu zapytania?

Co ważniejsze, w rzeczywistości chcę użyć przygotowania/wykonania, więc mam nadzieję, że odpowiedź pozwoli również na to.

+1

Czy próbowałeś, jak przykład na stronie podręcznika? '$ sql =" EXEC stp_Create_Item @Item_ID =?, @Item_Name =? ";' http://php.net/manual/en/function.sqlsrv-prepare.php ...lub nie przykłady, ale z "User Contributed Notes" – chris85

+0

Przeczytałem notatki autorstwa użytkownika na stronie sqlsrv_query, ale oczywiście nie przeczytałem ani nie zauważyłem tego przykładu na połączonej stronie. To najwyraźniej jest sposobem na zrobienie tego. Czy chcesz dodać to jako odpowiedź, aby móc oznaczyć ją dla przyszłych wyszukiwań? W przeciwnym razie to zrobię. – LittleTreeX

Odpowiedz

6

Składki użytkowników na php.net mają zapis o tym, jak wykonać procedurę składowaną za pomocą funkcji sqlsrv-prepare.

W przypadku, gdy zostanie usunięty z wkładu użytkowników php.net w przyszłości tutaj jest to, co miał (ma) wymieniono:

$procedure_params = array(
array(&$myparams['Item_ID'], SQLSRV_PARAM_OUT), 
array(&$myparams['Item_Name'], SQLSRV_PARAM_OUT) 
); 
// EXEC the procedure, {call stp_Create_Item (@Item_ID = ?, @Item_Name = ?)} seems to fail with various errors in my experiments 
$sql = "EXEC stp_Create_Item @Item_ID = ?, @Item_Name = ?"; 
$stmt = sqlsrv_prepare($conn, $sql, $procedure_params); 

Oto strona podręcznika, http://php.net/manual/en/function.sqlsrv-prepare.php

3

Jest to kontynuacja aż do odpowiedzi @ chris85.

Warto zauważyć tutaj, że gdy oświadczenie jest przygotowany, trzeba ją wykonać:

$sql = "EXEC stp_Create_Item @Item_ID = ?, @Item_Name = ?"; 
$stmt = sqlsrv_prepare($conn, $sql, $procedure_params); 
if (!sqlsrv_execute($stmt)) { 
    echo "Your code is fail!"; 
    die; 
} 
while($row = sqlsrv_fetch_rows($stmt)){ 
    //Stuff 
} 

sqlsrv_execute() tylko zwraca true/false. Jeśli chcesz przeanalizować dane zwrócone przez procedurę przechowywaną, możesz je przetworzyć podobnie jak wynik z sqlsrv_query().

Jeśli zapomnisz sqlsrv_execute(), otrzymasz komunikat, że wynik musi zostać wykonany, zanim będzie można go użyć.

+0

Nie wiesz, dlaczego głosowanie w dół? – AndyD273