4

PostgreSQL/plpgsqlに次のシグネチャを持つ関数があります。

CREATE OR REPLACE FUNCTION user_login(TEXT, TEXT) RETURNS SETOF _get_session AS $$ ... $$

ビューはどこ_get_sessionにありますか。この関数はphpPgAdminから呼び出すと正常に機能しますが、PHPから呼び出すと、次のエラーが発生します。

警告:pg_query()[function.pg-query]:クエリに失敗しました:エラー:タイプ「session_ids」が存在しませんコンテキスト:/home/sites/blah.com/indexの2行目近くにあるPL/pgSQL関数「user_login」のコンパイル69行目の.php

関数のDECLAREセクションには、次の変数が含まれています。

oldSessionId session_ids := $1;
newSessionId session_ids := $2;

ドメインsession_idsは存在し、同じドメインを使用する他の関数は、同じスクリプトから呼び出されたときに機能します。PHPは次のとおりです。

$query = "SELECT * FROM $dbschema.user_login('$session_old'::TEXT, '$session'::TEXT)";
$result = pg_query($login, $query);

関数を呼び出すときの::session_ids代わりにを使用してこれも試しましたが、同じエラーが発生します。::TEXT

ヘルプ:o(

4

2 に答える 2

1

コードを単純にするだけです。

$query = "SELECT * FROM $dbschema.user_login($1, $2)";
$result = pg_query_params($login, $query, array($session_old, $session));

これで、SQL インジェクションから安全になりました。

しかし、関数はまだ間違っています。データ型「session_ids」はありません。DECLARE 部分で TEXT を使いたいと思います。

于 2010-04-19T16:16:09.297 に答える
1

クエリが複数の行にまたがる場合、PHP はそれらを同じトランザクションの一部として送信しない可能性が高くなります。この場合、2 つのオプションがあります。

最初のオプションは、同じ呼び出しですべてのクエリを送信することです

pg_query("query1; query2; query3;");

2 番目のオプション (そして私の意見では最良) は、トランザクションを使用することです。これにより、複数の行にわたって呼び出しを行うことができますが、最初のクエリで begin ステートメントを送信する必要がある可能性が高くなります。

pg_query("begin; query1;");
pg_query("query2;");
pg_query("commit;");

エラーが発生した場合は、コミットをロールバックに置き換えます。データベースは変更されません。

Postgres を使用する場合、これは実際にはとにかく従うべき良い経験則です。

于 2010-05-19T15:38:10.317 に答える