2

私は何年もの間、開発で次のスニペットを使用してきました。突然、DB Error: no such field warning が表示されます

$process = "process";
$create = $connection->query
(
    "INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));

でも数値を使えばいい

$process = "12345";
$create = $connection->query
(
    "INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));

または値を式に直接書き込みます

$create = $connection->query
(
    "INSERT INTO summery (process) VALUES('process')"
);
if (DB::isError($create)) die($create->getMessage($create));

私は本当に混乱しています...何か提案はありますか?

4

2 に答える 2

7

準備されたクエリとパラメーター プレースホルダーを使用することを常にお勧めします。Perl DBI では次のようになります。

my $process=1234;
my $ins_process = $dbh->prepare("INSERT INTO summary (process) values(?)");
$ins_process->execute($process);

最高のパフォーマンスを得るには、データベース接続を開いた直後に、よく使用するすべてのクエリを準備します。多くのデータベース エンジンは、小さな一時ストアド プロシージャのように、セッション中にそれらをサーバーに格納します。

また、セキュリティにも非常に優れています。自分で挿入文字列に値を書き込むということは、各 SQL ステートメントで正しいエスケープ コードを記述する必要があることを意味します。準備と実行スタイルを使用すると、エスケープが必要な場合でも、エスケープについて知る必要があるのは1 つの場所 (実行) だけになります。

于 2008-11-30T19:36:53.890 に答える
0

Zan Lynx がプレースホルダーについて言ったことと同じです。しかし、コードがなぜ失敗したのか、まだ疑問に思っているかもしれません。

何年にもわたって機能していた以前のコードの重要な詳細を忘れているようです: 引用符.

この(テスト済みの)コードは正常に動作します:

my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
                              VALUES (3,'$thing')");
$sth->execute;

しかし、この次のコード (最初の例と同じように VALUES フィールドに引用符がない) では、報告したエラーが発生します。これは、VALUES (3,$thing) が VALUES (3,abcde) に解決され、SQL サーバーがフィールドを検索するためです。 abcde という名前で、その名前のフィールドはありません。

my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
                              VALUES (3,$thing)");
$sth->execute;

これはすべて、最初の例が、説明どおりに失敗したコードの直接の引用ではなく、したがって意図したものではないことを前提としています。次のように解決されます。

"INSERT INTO summery (process) VALUES(process)"

これにより、前述のように、SQL サーバーは VALUES セット内の項目を別のフィールド名として読み取ります。与えられたように、これは実際には問題なく MySQL で実行され、「プロセス」と呼ばれるフィールドに NULL が入力されます。これは、MySQL が新しいレコードを作成するときに値を検索したときに「プロセス」と呼ばれるフィールドに含まれていたものだからです。

私はこのスタイルを、既知の安全なデータ (たとえば、プログラム自体で提供される値) を含む簡単な使い捨てハックに使用します。しかし、プログラムの外部からのデータや、[0-9a-zA-Z] 以外を含む可能性のあるデータを含むものについては、プレースホルダーを使用することで問題を解決できます。

于 2008-12-01T04:24:33.217 に答える