1. ホーム
  2. database

[解決済み】PostgreSQL - SQLの状態です。42601構文エラー

2022-02-22 20:12:10

質問

関数内で動的クエリを使用する方法を知りたいです。いろいろ試してみましたが、関数をコンパイルしようとすると、SQL 42601というメッセージが表示されます。

私が使っているコード

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS 
$$
BEGIN
  WITH v_tb_person AS (return query execute sql)
  select name, count(*) from v_tb_person where nome like '%a%' group by name
  union
  select name, count(*) from v_tb_person where gender = 1 group by name;
END     
$$ LANGUAGE plpgsql;

受信したエラーメッセージ

ERROR:  syntax error at or near "return"
LINE 5:     WITH v_tb_person AS (return query execute sql)

を使ってみました。

WITH v_tb_person AS (execute sql)

WITH v_tb_person AS (query execute)

WITH v_tb_person AS (return query execute)

何が問題なのでしょうか?どうすればこの問題を解決できますか?

に関連する質問です。 Oracleの "bulk collect "に相当するPostgreSQLの機能

どのように解決するのですか?

関数は次のように動作します。

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS 
$$
BEGIN

RETURN QUERY EXECUTE '
WITH v_tb_person AS (' || sql || $x$)
SELECT name, count(*)::int FROM v_tb_person WHERE nome LIKE '%a%' GROUP BY name
UNION
SELECT name, count(*)::int FROM v_tb_person WHERE gender = 1 GROUP BY name$x$;

END     
$$ LANGUAGE plpgsql;

呼び出す。

SELECT * FROM prc_tst_bulk($$SELECT a AS name, b AS nome, c AS gender FROM tbl$$)

  • あなたが行おうとした方法では、プレーンなSQLとダイナミックなSQLを混在させることはできません。ステートメント全体がすべてダイナミックSQLか、すべてプレーンSQLになってしまいます。そこで、これを実現するために動的なステートメントを一つ作っているのです。についての章に興味があるかもしれません。 マニュアルにあるダイナミックコマンドの実行 .

  • 集計機能 count() は以下を返します。 bigint しかし、あなたは rowcount として定義されています。 integer そのため、明示的なキャストが必要です。 ::int を実行します。

  • 私は ドルクオート を使用することで、クォート地獄を回避することができます。

しかし であるべきなのでしょうか? のハニーポット SQLインジェクション それとも本気で使うつもりですか?プライベートで安全に使うのであれば、大丈夫かもしれませんが、私ならそのような関数を自分自身に託すことはしないでしょう。信頼できないユーザーがアクセスする可能性がある場合、そのような関数は装填された拳銃です。それは不可能です。 これを安全にする。

クレイグ(SQLインジェクションの宿敵!)は、あなたが彼のコードから偽造したものを見て、軽い発作を起こすかもしれません。 前の質問 . :)

クエリ自体がかなり変な感じですね、乙です。しかし、それはここでは問題外です。