错误:类型"执行"不存在

Kyl*_*win 2 postgresql plpgsql

我正在尝试编写一个PL/PgSQL函数,它将执行存储在PostgreSQL表中的查询,如下所示:

CREATE OR REPLACE FUNCTION evaluate_scenario(scenario_id int)
RETURNS TABLE(line_item_id int, organization_id int, data_element_id int, value varchar) AS $$
BEGIN
  RETURN QUERY
  SELECT
    li.id,
    li.organization_id,
    de.id,
    (EXECUTE 'SELECT ' || de.query)::varchar
  FROM
    line_items AS li INNER JOIN
    summary_files AS sf ON li.summary_file_id = sf.id INNER JOIN
    scenarios AS s ON s.summary_file_id = sf.id CROSS JOIN
    data_elements AS de
  WHERE
    s.id = 1 AND
    de.scope = 3 AND (
      de.model_id = s.model_id OR
      de.scenario_id = s.id OR
      de.organization_id = s.organization_id
    );
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

当我尝试运行此查询时:

select line_item_id, data_element_id, value from evaluate_scenario(1)

我收到以下错误:

********** Error **********

ERROR: type "execute" does not exist
SQL state: 42704
Context: PL/pgSQL function "evaluate_scenario" line 3 at RETURN QUERY
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.请注意,如果我删除"EXECUTE"并在那些parens中执行SELECT de.query,我会按预期收到该列的值,但我无法弄清楚如何使de.query成为"EXECUTE"的可接受查询字符串".

Erw*_*ter 5

EXECUTE将查询字符串作为参数并执行它,但不能嵌套 EXECUTE在查询中.

EXECUTEplpgsql 中有几个变种.对于您的情况,RETURN QUERY EXECUTE query可能是最好的.阅读手册.

这可能有用 - 我不是要修复所有的混乱,只是展示一个工作的例子.

CREATE OR REPLACE FUNCTION evaluate_scenario(_scenario_id int)
RETURNS TABLE(line_item_id int, organization_id int, data_element_id int, value varchar) AS
$func$

BEGIN
  RETURN QUERY EXECUTE '
  SELECT li.id,
         li.organization_id,
         de.id,
        (SELECT '
|| (SELECT query
    FROM   data_elements
    WHERE  scenario_id = _scenario_id)
|| ')
  FROM   line_items AS li
  JOIN   summary_files AS sf ON li.summary_file_id = sf.id
  JOIN   scenarios AS s ON s.summary_file_id = sf.id
  CROSS  JOIN data_elements AS de
  WHERE  s.id = 1
  AND    de.scope = 3
  AND   (de.model_id = s.model_id OR
         de.scenario_id = s.id OR
         de.organization_id = s.organization_id
        )';

END;
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

请注意,将文本文字作为代码执行本质上是不安全的.如果有人可以将一个DROP * FROM tbl或一些这样的人走私到桌子上data_elements,那你就麻烦大了.我说的是SQL注入.
在bobby-tables.com上阅读有关SQLi的更多信息.