如何在 PL/pgSQL 函数中将 WITH 与 IF 一起使用

问题描述

subprocess.run(shlex.split(entry1.get()))
CREATE OR REPLACE FUNCTION test()
RETURNS boolean security definer AS
$BODY$

BEGIN

with zzz as (select foo from data)

 IF EXISTS (select 1 from zzz) THEN
 
  return true;
  
  ELSE
     return false;
  END IF;

END;
$BODY$
LANGUAGE plpgsql VOLATILE;

问题出在哪里?

解决方法

简化为单个 return 语句:

return exists(select foo from data);
,

就像 Bohemian 提供的那样,您可以从根本上简化为:

RETURN EXISTS(SELECT foo FROM data);

然而,这表明 foo 很重要,它并不重要(如果该列存在,否则会引发异常)。 EXISTS 如果至少返回一行,则返回 true,无论内容如何:为此目的甚至可以全部为 NULL 值。否则返回 false。从不null。减少误导:

RETURN EXISTS(SELECT * FROM data);
RETURN EXISTS(SELECT 1 FROM data);

Postgres 也接受一个空的 SELECT 列表(我的偏好):

RETURN EXISTS(SELECT FROM data);

见:

或者在简单的情况下使用语法简写 TABLE

RETURN EXISTS(TABLE data);

见:

PL/pgSQL 对于简单的情况来说是多余的,一个普通的 SQL 函数或者只是一个裸语句都可以:

SELECT EXISTS(TABLE data);

为了将逻辑集成到更复杂的 PL/pgSQL 函数中,特殊变量 FOUND(如 Adrian commented)通常是有用的。或者 GET DIAGNOSTICS ... 用于动态 SQL。

见:

,

最后我使用了:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {

  String initialRoute;

  // handle exceptions caused by making main async
  WidgetsFlutterBinding.ensureInitialized();

  // init a shared preferences variable
  SharedPreferences prefs = await SharedPreferences.getInstance();
  
  // read token
  String token = prefs.getString('token');

  // use dart's null safety operater
  if (token?.isEmpty ?? true)
    initialRoute = 'login';
  else
    initialRoute = '/';

  // create a flutter material app as usual
  Widget app = MaterialApp(
    ...
    initialRoute: initialRoute,);

  // mount and run the flutter app
  runApp(app);
}