mirror of
https://github.com/supabase/supabase.git
synced 2026-07-02 18:34:44 +08:00
304 lines
6.3 KiB
Plaintext
304 lines
6.3 KiB
Plaintext
---
|
|
id: functions
|
|
title: Functions
|
|
description: Creating and using Postgres functions.
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
import TabsPanel from '@theme/TabsPanel';
|
|
|
|
|
|
Postgres has built-in support for [SQL functions](https://www.postgresql.org/docs/current/sql-createfunction.html).
|
|
These functions live inside your database, and they can be [used with the API](/docs/reference/javascript/rpc).
|
|
|
|
## Quick demo
|
|
|
|
<iframe
|
|
className="w-full video-with-border"
|
|
width="640"
|
|
height="385"
|
|
src="https://www.youtube-nocookie.com/embed/MJZCCpCYEqk"
|
|
frameBorder="1"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowFullScreen
|
|
></iframe>
|
|
|
|
## Creating Functions
|
|
|
|
Supabase provides several options for creating database functions. You can use the Dashboard or create them directly using SQL.
|
|
We provide a SQL editor within the Dashboard, or you can [connect](/docs/guides/database/connecting/connecting-to-postgres) to your database
|
|
and run the SQL queries yourself.
|
|
|
|
|
|
1. Go to the "SQL editor" section.
|
|
2. Click "New Query".
|
|
3. Enter the SQL to create or replace your Database function.
|
|
4. Click "Run" or cmd+enter (ctrl+enter).
|
|
|
|
## Examples
|
|
|
|
### Data set
|
|
|
|
For this guide we'll use the following example data:
|
|
|
|
|
|
<Tabs
|
|
defaultActiveId="Data"
|
|
values={[
|
|
{label: 'Data', value: 'Data'},
|
|
{label: 'SQL', value: 'SQL'},
|
|
]}>
|
|
|
|
<TabsPanel id="SQL" label="SQL">
|
|
|
|
```sql
|
|
create table planets (
|
|
id serial primary key,
|
|
name text
|
|
);
|
|
|
|
insert into planets (id, name)
|
|
values
|
|
(1, 'Tattoine'),
|
|
(2, 'Alderaan'),
|
|
(3, 'Kashyyyk');
|
|
|
|
create table people (
|
|
id serial primary key,
|
|
name text,
|
|
planet_id bigint references planets
|
|
);
|
|
|
|
insert into people (id, name, planet_id)
|
|
values
|
|
(1, 'Anakin Skywalker', 1),
|
|
(2, 'Luke Skywalker', 1),
|
|
(3, 'Princess Leia', 2),
|
|
(4, 'Chewbacca', 3);
|
|
```
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="Data" label="Data">
|
|
|
|
<h4>Planets</h4>
|
|
|
|
| id | name |
|
|
| ---- | ---- |
|
|
| 1 | Tattoine |
|
|
| 2 | Alderaan |
|
|
| 3 | Kashyyyk |
|
|
|
|
<h4>People</h4>
|
|
|
|
| id | name | planet_id |
|
|
| ---- | ---- | ---- |
|
|
| 1 | Anakin Skywalker | 1 |
|
|
| 2 | Luke Skywalker | 1 |
|
|
| 3 | Princess Leia | 2 |
|
|
| 4 | Chewbacca | 3 |
|
|
|
|
</TabsPanel>
|
|
|
|
</Tabs>
|
|
|
|
### Basic function
|
|
|
|
A basic example which returns a string "hello world".
|
|
|
|
```sql
|
|
create or replace function hello_world() -- 1
|
|
returns text -- 2
|
|
language sql -- 3
|
|
as $$ -- 4
|
|
select 'hello world'; -- 5
|
|
$$; --6
|
|
|
|
```
|
|
|
|
<details>
|
|
<summary>Show/Hide Details</summary>
|
|
|
|
At it's most basic a function has the following parts:
|
|
|
|
1. `create or replace function hello_world()`: The function declaration, where `hello_world` is the name of the function. You can use either `create` when creating a new function or `replace` when replacing an existing function. Or you can use `create or replace` together to handle either.
|
|
2. `returns text`: The type of data that the function returns. If it returns nothing, you can `returns void`.
|
|
3. `language sql`: The language used inside the function body. This can also be a procedural language: `plpgsql`, `plv8`, `plpython`, etc.
|
|
4. `as $$`: The function wrapper. Anything enclosed inside the `$$` symbols will be part of the function body.
|
|
5. `select 'hello world';`: A simple function body. The final `select` statement inside a function body will be returned if there are no statements following it.
|
|
6. `$$;`: The closing symbols of the funciton wrapper.
|
|
|
|
</details>
|
|
|
|
#### Execute
|
|
|
|
<Tabs
|
|
defaultActiveId="SQL"
|
|
values={[
|
|
{label: 'SQL', value: 'SQL'},
|
|
{label: 'JS', value: 'JS'},
|
|
{label: 'Dart', value: 'Dart'},
|
|
]}>
|
|
|
|
<TabsPanel id="SQL" label="SQL">
|
|
|
|
```sql
|
|
select hello_world();
|
|
```
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="JS" label="JS">
|
|
|
|
```js
|
|
const { data, error } = supabase
|
|
.rpc('hello_world')
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/javascript/rpc)
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="Dart" label="Dart">
|
|
|
|
```dart
|
|
final res = await supabase
|
|
.rpc('hello_world')
|
|
.execute();
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/dart/rpc)
|
|
|
|
</TabsPanel>
|
|
|
|
</Tabs>
|
|
|
|
|
|
### Return table sets
|
|
|
|
A basic example which return all the `planets` in our example data set.
|
|
|
|
```sql
|
|
create or replace function get_planets()
|
|
returns setof planets
|
|
language sql
|
|
as $$
|
|
select * from planets;
|
|
$$;
|
|
```
|
|
|
|
#### Execute
|
|
|
|
Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the first planet:
|
|
|
|
<Tabs
|
|
defaultActiveId="SQL"
|
|
values={[
|
|
{label: 'SQL', value: 'SQL'},
|
|
{label: 'JS', value: 'JS'},
|
|
{label: 'Dart', value: 'Dart'},
|
|
]}>
|
|
|
|
<TabsPanel id="SQL" label="SQL">
|
|
|
|
```sql
|
|
select *
|
|
from get_planets()
|
|
where id = 1;
|
|
```
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="JS" label="JS">
|
|
|
|
```js
|
|
const { data, error } = supabase
|
|
.rpc('get_planets')
|
|
.eq('id', 1)
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/javascript/rpc)
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="Dart" label="Dart">
|
|
|
|
```dart
|
|
final res = await supabase
|
|
.rpc('get_planets')
|
|
.eq('id', 1)
|
|
.execute();
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/dart/rpc)
|
|
|
|
</TabsPanel>
|
|
|
|
</Tabs>
|
|
|
|
|
|
### With parameters
|
|
|
|
A basic example which will insert a new planet into the `planets` and return the new ID. Note that this time we're using the `plpgsql` language.
|
|
|
|
```sql
|
|
create or replace function add_planet(name text)
|
|
returns bigint
|
|
language plpgsql
|
|
as $$
|
|
declare
|
|
new_row bigint;
|
|
begin
|
|
insert into planets(name)
|
|
values (add_planet.name)
|
|
returning id into new_row;
|
|
|
|
return new_row;
|
|
end;
|
|
$$;
|
|
```
|
|
|
|
#### Execute
|
|
|
|
Because this function returns a table set, we can also apply filters and selectors. For example, if we only wanted the `name` of the first planet:
|
|
|
|
<Tabs
|
|
defaultActiveId="SQL"
|
|
values={[
|
|
{label: 'SQL', value: 'SQL'},
|
|
{label: 'JS', value: 'JS'},
|
|
{label: 'Dart', value: 'Dart'},
|
|
]}>
|
|
|
|
<TabsPanel id="SQL" label="SQL">
|
|
|
|
```sql
|
|
select * from add_planet('Jakku');
|
|
```
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="JS" label="JS">
|
|
|
|
```js
|
|
const { data, error } = supabase
|
|
.rpc('add_planet', { name: 'Jakku' })
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/javascript/rpc)
|
|
|
|
</TabsPanel>
|
|
<TabsPanel id="Dart" label="Dart">
|
|
|
|
```dart
|
|
final res = await supabase
|
|
.rpc('add_planet', params: { 'name': 'Jakku' })
|
|
.execute();
|
|
```
|
|
|
|
Reference: [rpc()](/docs/reference/dart/rpc)
|
|
|
|
</TabsPanel>
|
|
|
|
</Tabs>
|
|
|
|
|
|
## Resources
|
|
|
|
- PostgreSQL Official Docs: [Chapter 9. Functions and Operators](https://www.postgresql.org/docs/current/functions.html)
|
|
- PostgreSQL Reference: [CREATE FUNCTION](https://www.postgresql.org/docs/9.1/sql-createfunction.html)
|