动态SQL(EXECUTE)作为IF语句的条件

Mat*_*att 11 postgresql dynamic-sql plpgsql

我想执行一个动态SQL语句,其返回值是IF语句的条件:

IF EXECUTE 'EXISTS (SELECT 1 FROM mytable)' THEN
Run Code Online (Sandbox Code Playgroud)

这会产生错误ERROR: type "execute" does not exist.

是否可以这样做,或者是否有必要在IF语句之前执行SQL变量,然后将变量检查为条件?

Erw*_*ter 20

这种结构是不可能的:

IF EXECUTE 'EXISTS (SELECT 1 FROM mytable)' THEN ...

您可以简化为:

IF EXISTS (SELECT 1 FROM mytable) THEN ...
Run Code Online (Sandbox Code Playgroud)

但你的例子可能只是简化了.对于执行的动态SQLEXECUTE,请阅读此处的手册.您可以在以下FOUND后查看RETURN QUERY EXECUTE:

IF FOUND THEN ...
Run Code Online (Sandbox Code Playgroud)

然而:

请特别注意,EXECUTE更改输出GET DIAGNOSTICS,但不会更改FOUND.

大胆强调我的.对于普通人而言EXECUTE:

...
DECLARE
   i int;
BEGIN
   EXECUTE 'SELECT 1 FROM mytable';

   GET DIAGNOSTICS i = ROW_COUNT;

   IF i > 0 THEN ...
Run Code Online (Sandbox Code Playgroud)

或者,如果时机-尤其是只有单排的结果-使用INTO条款EXECUTE获得直接的动态查询的结果.我在这里引用手册:

如果提供了行或变量列表,则它必须与查询结果的结构完全匹配(当使用记录变量时,它将自行配置以自动匹配结果结构).如果返回多行,则只将第一行分配给 INTO变量.如果没有返回任何行,则为INTO 变量分配NULL .

...
DECLARE
   _var1 int;  -- init value is NULL unless instructed otherwise
BEGIN

EXECUTE format('SELECT var1 FROM %I WHERE x=y LIMIT 1', 'my_Table')
INTO    _var1;

IF _var1 IS NOT NULL THEN ...
Run Code Online (Sandbox Code Playgroud)


小智 7

马特,

从上面的语法,你正在编写PL/pgSQL,而不是SQL.假设有两种方法可以做你想要的,但两者都需要两行代码:

EXECUTE 'SELECT EXISTS (SELECT 1 FROM ' || table_variable || ' );' INTO boolean_var;

IF boolean_var THEN ...
Run Code Online (Sandbox Code Playgroud)

要么:

EXECUTE 'SELECT 1 FROM ' || table_variable || ' );';

IF FOUND THEN ...
Run Code Online (Sandbox Code Playgroud)

"FOUND"是一个特殊变量,用于检查上次查询运行是否返回任何行.

  • 你错了'FOUND`.它不是由普通的EXECUTE设置的.详情请见我的回答. (2认同)