在 PostgreSQL 中有没有办法自动对查询施加限制?

In PostgreSQL is there a way to impose a LIMIT to queries automatically?

初始问题

在 PostgreSQL 中有没有办法自动将 LIMIT 子句强加给查询?

假设我有一个 table restaurant:

create table restaurant (
  id uuid primary key,
  name text,
  created_at timestamp)

首先,我尝试了一个视图:

create view restaurant_limited 
as 
select * 
from restaurant 
order by created_at 
limit 3;

问题在于您无法应用谓词并让它起作用,因为谓词在 LIMIT.

之后应用

接下来,我考虑重写规则。但是,据我所知,规则系统允许您替换一个新的查询,但它并没有给您很大的权力重写一个现有的查询。

接下来,我考虑了触发器,但触发器似乎只适用于 DML,不适用于查询。

我想一个函数或一个过程可以做到这一点,但现在我们正在摆脱纯 SQL 接口的领域。 当然一定有办法做到这一点。有什么想法吗?

附录

我不想先应用谓词然后再应用 LIMIT 的原因是因为我希望它是通用的并支持多种查询模式。如果用户可以提交或多或少的任何查询,那么我不会提前知道谓词。本质上,我想要的是逻辑设计,如果不是物理设计,就会是这样的东西。

  1. 接受针对给定 table.
  2. 的任意 SELECT 查询
  3. 将该查询视为外部查询的子查询。
  4. 在该外部查询中自动添加一个 LIMIT 子句。

我绝对可以在 SQL 控制台上执行此操作。如果 SQL 是在中间层内生成的(例如,Python 或 Java),我也可以在中间层执行此操作。我希望的是 PostgreSQL 中有某种方法可以自动执行此操作。

当然,我想得越多,我就越意识到这不会是任何特定 table 的 属性,就像触发器或重写规则一样。事实上,将其应用于个人关系甚至没有任何意义。它将 成为适用于 所有 查询的重写规则。这听起来不错,也许它在某些扩展中可用,但如果在 PostgreSQL.

中没有本地方法可以做到这一点,我不会感到惊讶

据我所知,无法按照您想要的方式更改 SQL 查询的含义。

实现这一点的规范方法是使用游标:

BEGIN;  -- cursors need a transaction

DECLARE c CURSOR FOR SELECT ...;

FETCH 50 FROM c;

COMMIT;

这是 SQL 中的游标,但您的客户端 API 也可以通过某种方式声明游标。

如果您愿意通过代理,您可以根据自己的喜好重写请求(和响应)——参见 https://dzone.com/articles/query-substitution

在您的情况下,代理中的几行代码应该允许您在需要时将限制添加到 SQL。