数据库函数
Postgres内置了对SQL函数的支持。 这些函数存在于你的数据库中,它们可以与API一起使用。
快速演示
开始使用
Supabase 为创建数据库函数提供了几个选项。你可以使用仪表板或直接使用 SQL 创建它们。 我们在 Dashboard 中提供了一个 SQL 编辑器,或者你可以 连接 到数据库并自己运行SQL查询。
- 进入
SQL编辑器
栏。 - 点击
新查询
。 - 输入创建或替换数据库功函数的SQL。
- 点击
运行
或cmd+enter (ctrl+enter)。
简单的函数
让我们创建一个基本的数据库函数,返回一个字符串 hello world
.
1create or replace function hello_world() -- 1 2returns text -- 2 3language sql -- 3 4as $$ -- 4 5 select 'hello world'; -- 5 6$$; --6
显示/隐藏细节
最基本的是,一个函数有以下部分:
create or replace function hello_world()
。函数声明,其中hello_world
是函数的名称。你可以在创建一个新的函数时使用create
,或者在替换一个现有函数时使用replace
。或者你可以同时使用create或replace
来处理这两种情况。returns text
: 函数返回的数据类型。如果它什么都不返回,你可以returns void
。language sql': 在函数主体中使用的语言。这也可以是一种程序性语言:
plpgsql,
plv8,
plpython`等。as $$
: 函数包装器。任何包含在$$
符号中的东西都将是函数主体的一部分。select 'hello world';
: 一个简单的函数体。如果函数体中的最后一条select
语句后面没有语句,将被返回。$$;
: 函数封装器的结束符号。
函数创建后,我们有几种 "执行 "函数的方法--可以直接在数据库中使用SQL,也可以使用其中一个客户端库。
1select hello_world();
返回数据集
数据库函数也可以从数据表或视图中返回数据集。
例如,如果我们有一个数据库,里面有一些星球大战的数据。
Planets
id | name |
---|---|
1 | Tattoine |
2 | Alderaan |
3 | Kashyyyk |
People
id | name | planet_id |
---|---|---|
1 | Anakin Skywalker | 1 |
2 | Luke Skywalker | 1 |
3 | Princess Leia | 2 |
4 | Chewbacca | 3 |
我们可以创建一个函数,返回所有的星球:
1create or replace function get_planets()
2returns setof planets
3language sql
4as $$
5 select * from planets;
6$$;
因为这个函数返回一个表集,我们也可以应用过滤器和选择器。例如,如果我们只想要第一个星球:
1select *
2from get_planets()
3where id = 1;
传递参数
让我们创建一个函数,在planets
表中插入一个新的行星并返回新的ID。注意,这次我们使用的是plpgsql
语言。
1create or replace function add_planet(name text) 2returns bigint 3language plpgsql 4as $$ 5declare 6 new_row bigint; 7begin 8 insert into planets(name) 9 values (add_planet.name) 10 returning id into new_row; 11 12 return new_row; 13end; 14$$;
再一次,你可以在数据库中使用select
查询来执行这个函数,或者使用客户端库。
1select * from add_planet('Jakku');
建议
数据库函数vs边缘函数#
对于数据密集型的操作,使用数据库函数,它在你的数据库中执行并可以使用REST和GraphQL API远程调用。
对于需要低延迟的使用情况,使用边缘函数,它是全局分布的,可以用Typescript编写。
安全性 definer
vs invoker
#
Postgres允许你指定是作为调用函数的用户(invoker
),还是作为函数的创建者(definer
)来执行函数。比如说:
1create function hello_world()
2returns text
3language plpgsql
4security definer set search_path = public
5as $$
6begin
7 select 'hello world';
8end;
9$$;
最好的做法是使用security invoker
(这也是默认的)。如果你使用security definer
,你必须设置search_path
。
这限制了潜在的损害,如果你允许访问执行该函数的用户不应该有的模式。
函数的权限
默认情况下,数据库函数可以由任何角色执行。你可以通过改变默认权限来限制这一点,然后选择哪些角色可以执行功能。
1ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC; 2 3-- Choose which roles can execute functions 4GRANT EXECUTE ON FUNCTION hello_world TO authenticated; 5GRANT EXECUTE ON FUNCTION hello_world TO service_role;
资源
- 官方客户端库: JavaScript and Flutter
- 社区客户端库: github.com/supabase-community
- PostgreSQL官方文档: 第9章 函数和运算符
- PostgreSQL参考资料: 创建函数