Note for MySQL: to use input/output parameters for stored procedures with PDO use PDO.Query() statement.
For example:
<?php
$dbh->query("CAST SomeStoredProcedure($someInParameter1, $someInParameter2, @someOutParameter)");
$dbh->query("SELECT @someOutParameter");
?>
Or, if you want very much to use PDO.Prepare(), insert "SELECT @someOutParameter" in your stored procedure and then use:
<?php
$stmt = $dbh->prepare("CAST SomeStoredProcedure(?, ?)");
$stmt ->execute(array($someInParameter1, $someInParameter2));
?>
Hazır deyimler ve Saklı Yordamlar
Genellikle gelişkin veritabanlarınca desteklenen, hazır deyimler diye bilinen bir kavram vardır. Bunlar nedir? Bunları bir takım değiştirgelerle özelleştirilebilen, SQL için derlenmiş şablonlar olarak düşünebilirsiniz. Hazır deyimlerin başlıca iki yararı vardır:
- Sorgunun tek bir defa çözümlenmesi (veya hazırlanması) gerekir fakat aynı veya farklı değiştirgelerle defalarca çalıştırılabilir. Sorgu hazır olduğunda veritabanınca incelenir, derlenip sorgunun amacına uygun olarak en iyilenir. Karmaşık sorgularda aynı sorguyu farklı değiştirgelerle defalarca yineleyecekseniz işlemler, uygulamanızı farkedilir şekilde yavaşlatacak kadar uzun sürebilir. Hazır deyimleri kullanarak her yinelemede tekrarlanan inceleme/derleme/eniyileme döngüsünden kurtulabilirsiniz. Özetle, hazır deyimler daha az özkaynak kullandığından daha hızlı çalışır.
- Hazır deyim değiştirgelerinin öncelenmesi gerekmez. Bu işlemi sürücüler sizin yerinize yapar. Uygulamanız özellikle hazır deyimleri kullanıyorsa hiçbir SQL zerkinin olmayacağından emin olabilirsiniz. (Ancak, sorgunun diğer parçaları öncelenmemiş girdiler içeriyorsa hala risk altındasınız demektir.)
Hazır deyimleri kullanmanın bir başka yararı da bunları desteklemeyen sürücüler için PDO'nun bu özelliği taklit etmesidir (PDO'nun taklit ettiği tek özellik budur). Böylece aynı veri erişim uygulamasını veritabanınızın yeteneklerinden bağımsız olarak kullanabilirsiniz.
Örnek 1 - Hazır deyimlerle değiştirge ismine göre veri girişi
Bu örnekte isim ve deger alanlarına değiştirgelerin isimlerine göre bir INSERT sorgusu ile defalarca veri girilmektedir.
<?php
$deyim = $dbh->prepare(
"INSERT INTO KUTUK (isim, deger) VALUES (:isim, :deger)");
$deyim->bindParam(':isim', $isim);
$deyim->bindParam(':değer', $değer);
// bir satıra veri girelim
$isim = 'bir';
$değer = 1;
$deyim->execute();
// farklı değerlerle bir satır daha girelim
$isim = 'iki';
$değer = 2;
$deyim->execute();
?>
Örnek 2 - Hazır deyimlerle değiştirge indisine göre veri girişi
Bu örnekte isim ve deger alanlarına değiştirgelerin indislerine göre bir INSERT sorgusu ile defalarca veri girilmektedir.
<?php
$deyim = $dbh->prepare("INSERT INTO KUTUK (isim, değer) VALUES (?, ?)");
$deyim->bindParam(1, $isim);
$deyim->bindParam(2, $değer);
// bir satıra veri girelim
$isim = 'bir';
$değer = 1;
$deyim->execute();
// farklı değerlerle bir satır daha girelim
$isim = 'iki';
$değer = 2;
$deyim->execute();
?>
Örnek 3 - Hazır deyimle veri almak
Bu örnekte bir formdan sağlanan bir anahtar değere dayanarak veritabanından veri alınmaktadır. Kullanıcı girdisi özdevinimli olarak öncelenmekte, dolayısıya bir SQL zerki riski ortaya çıkmamaktadır.
<?php
$deyim = $dbh->prepare("SELECT * FROM KUTUK where isim = ?");
if ($deyim->execute(array($_GET['isim']))) {
while ($satır = $deyim->fetch()) {
print_r($satır);
}
}
?>
Eğer veritabanı sürücüsü değiştirge ilişkilendirmeyi destekiyorsa değiştirgeleri sadece girdide değil çıktıda da değiştirgelerle ilişkilendirebilirsiniz. Çıktı değiştirgelerinin kullanımı girdi değiştirgelerine göre daha karmaşıktır. Böyle bir durumda ilişkilendirdiğiniz değiştirge sayısını bilmeniz gerekir. Eğer dönen değer önerdiğinizden daha büyükse bir hata oluşur.
Örnek 4 - Bir saklı yordamın çıktı değiştirgesi ile kullanımı
<?php
$deyim = $dbh->prepare("CALL sy_dizge_döndürür(?)");
$deyim->bindParam(1, $dönen_değer, PDO::PARAM_STR, 4000);
// call the stored procedure
$deyim->execute();
print "dönen değer: $dönen_değer\n";
?>
Ayrıca, değerleri tutan değiştirgeleri hem girdi hem de çıktı için kullanabilirsiniz. Sonraki örnekte, saklı yordama 'merhaba' dizgesi aktarılmakta, yordam döndüğünde 'merhaba' yerine yordamın dönüş değeri yerleştirilmektedir.
Örnek 5 - Bir saklı yordamın girdi/çıktı değiştirgesi ile kullanımı
<?php
$deyim = $dbh->prepare("CALL sy_dizge_alır_dizge_döndürür(?)");
$değer = 'merhaba';
$deyim->bindParam(1, $değer, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// saklı yordamı çağıralım
$deyim->execute();
print "dönen değer: $değer\n";
?>
Örnek 6 - Geçersiz değiştirge kullanımı
<?php
$deyim = $dbh->prepare("SELECT * FROM KUTUK where isim LIKE '%?%'");
$deyim->execute(array($_GET['isim']));
// değiştirge değerin yerinde kullanılmalı
$deyim = $dbh->prepare("SELECT * FROM KUTUK where isim LIKE ?");
$deyim->execute(array("%$_GET[isim]%"));
?>
Note for MySQL: to use input/output parameters for stored procedures with PDO use PDO.Query() statement.
For example:
<?php
$dbh->query("CAST SomeStoredProcedure($someInParameter1, $someInParameter2, @someOutParameter)");
$dbh->query("SELECT @someOutParameter");
?>
Or, if you want very much to use PDO.Prepare(), insert "SELECT @someOutParameter" in your stored procedure and then use:
<?php
$stmt = $dbh->prepare("CAST SomeStoredProcedure(?, ?)");
$stmt ->execute(array($someInParameter1, $someInParameter2));
?>
Note that when using name parameters with bindParam, the name itself, cannot contain a dash '-'.
example:
<?php
$stmt = $dbh->prepare ("INSERT INTO user (firstname, surname) VALUES (:f-name, :s-name)");
$stmt -> bindParam(':f-name', 'John');
$stmt -> bindParam(':s-name', 'Smith');
$stmt -> execute();
?>
The dashes in 'f-name' and 's-name' should be replaced with an underscore or no dash at all.
See http://bugs.php.net/43130
Adam
You have to make attention to the parameters send to the method.
We can imagine that a request like that can work:
<?php
$query = 'SELECT ? FROM ? WHERE id = ?';
?>
But in fact, it's a hijack of prepared query, which MUST be used *ONLY* to change the condition (here the last '?' ).
You do not send my_table.my_row or my_scheme.my_table because this parameters are essentials to optimize the query before execution.
Other thing: prepared query can not be serialized to reuse it some time later. For that you can use a mask (http://fr2.php.net/singleton)
A prepared query is temporary.
