ホームページ  >  記事  >  バックエンド開発  >  準備されたステートメントとは何ですか?それの使い方?

準備されたステートメントとは何ですか?それの使い方?

王林
王林転載
2019-08-26 11:24:254702ブラウズ

成熟したデータベースの多くは、プリペアド ステートメントの概念 (Prepared Statements) をサポートしています。彼らは何ですか?これらは、実行されるコンパイルされた SQL ステートメント テンプレートと考えることができ、さまざまな変数パラメーターを使用してカスタマイズできます。準備済みステートメントには、次の 2 つの主な利点があります。

クエリは 1 回だけ解析 (または準備) する必要がありますが、同じまたは異なるパラメーターを使用して複数回実行できます。クエリが準備されると、データベースはクエリを実行するための計画を分析、コンパイル、最適化します。複雑なクエリの場合、パラメータは異なるが同じ構造のクエリを何度も繰り返し実行する必要がある場合、このプロセスに多くの時間がかかり、アプリケーションの速度が低下します。準備されたステートメントを使用すると、繰り返しの分析、コンパイル、最適化を回避できます。簡単に言うと、プリペアド ステートメントは使用するリソースが少なく、実行速度が速くなります。

準備されたステートメントに渡されるパラメーターは引用符で囲む必要はありません。これは、基礎となるドライバーが処理します。アプリケーションが準備されたステートメントのみを使用する場合、SQL インジェクションは発生しないことが保証されます。 (ただし、信頼できない入力に基づいてクエリの他の部分を構築している場合、これは依然として危険です。)

プリペアド ステートメントは非常に便利であるため、データベースによって提供されるモック実装に対して PDO が行う唯一のことはプリペアド ステートメントです。この機能をサポートしていないもの。これにより、データベース自体にこの機能があるかどうかを気にすることなく、統一されたデータ アクセス仕様を使用できるようになります。

/*
使用预处理语句重复插入数据(1)
此示例演示了一个通过向命名占位符代入一个name和一个value值来执行的INSERT查询
*/
连接数据库:$dbh = new PDO("mysql:host=127.0.0.1;dbname=dbname",'username','123');
注:如果插入数据后出现乱码的话,注意检查各个页面的字符集设置,尤其是关于pdo处理的php页面仅有header头设置为utf-8有时也不行,这时就在执行SQL语句前设置数据库的字符集$dbh->query("set names utf8");
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value); //插入一行
$name = 'one';
$value = 1;
$stmt->execute();//使用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();

/*
使用预处理语句重复插入数据(2)
此示例演示了一个通过向用?表示的占位符代入一个name和一个value值来执行的INSERT查询
*/
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value); // 插入一行
$name = 'one';
$value = 1;
$stmt->execute(); // 使用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();

/*
通过预处理语句获取数据
此示例演示使用从表单获取的数据为关键值来执行查询获取数据。用户的输入会被自动添加引号,所以这儿不存在SQL注入攻击的危险。
*/
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
    if ($stmt->execute(array($_GET['name']))) {
        while ($row = $stmt->fetch()) {
        print_r($row);
    }
}

データベース ドライバーがサポートしている場合は、入力パラメーターと同様に出力パラメーターをバインドすることもできます。出力パラメーターは、ストアド プロシージャからの戻り値としてよく使用されます。出力パラメータは入力パラメータよりも使用が若干複雑であるため、出力パラメータを使用する場合は、出力パラメータが返すパラメータ値のサイズを知っておく必要があります。提案した値よりも大きなパラメータ値が返された場合、エラーが発生します。

//调用一个带有输出参数的存储过程
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); //执行存储过程
$stmt->execute();
print "procedure returned $return_value/n";

入力と出力の両方を表すパラメーターを指定することもできます。構文は出力パラメーターと似ています。次のコード例では、「hello」文字列がストアド プロシージャに渡され、ストアド プロシージャが返されると、hello がストアド プロシージャの戻り値に置き換えられます。

//调用一个带有输入/输出参数的存储过程
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// 执行存储过程
$stmt->execute();
print "procedure returned $value/n";


//占位符的错误使用
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name'])); // 占位符必须用于整个值的位置(下面是正确的用法)
$stmt = $dbh->prepare(”SELECT * FROM REGISTRY where name LIKE ?”);
$stmt->execute(array(”%$_GET[name]%”));

エラーがある場合は、それを指摘してください。関連する問題をさらに知りたい場合は、PHP 中国語 Web サイトにアクセスしてください: PHP ビデオ チュートリアル

内容も解説も充実していて、納得のいく回答が得られると思います。

以上が準備されたステートメントとは何ですか?それの使い方?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。