您是否有任何理由需要通过一个电话来执行此操作?我从您的结构中假设您不会genre
为您创建的每本书都创建一个新的,所以大多数时候,您只是插入一条book
记录和一条book_gen_rel
记录。在现实世界中,您可能会拥有属于多种类型的书籍,因此最终您将更改您的函数以在一次调用中处理一本书的插入以及多种类型。
话虽如此,也有两种方法可以解决这个问题。您可以从客户端进行多个 API 调用(这样做确实没有问题——这很常见)。其次,如果您创建一个 PostgreSQL 函数并使用.rpc()
.
仅使用客户端调用在每个表中插入记录的示例:
const { data: genre_data, error: genre_error } = await supabase
.from('genre')
.insert([
{ name: 'Technology' }
]);
const genre_id = genre_data[0].id;
const { data: book_data, error: book_error } = await supabase
.from('book')
.insert([
{ name: 'The Joys of PostgreSQL' }
]);
const book_id = book_data[0].id;
const { data: book_genre_rel_data, error: book_genre_rel_error } = await supabase
.from('book_genre_rel_data')
.insert([
{ book_id, genre_id }
]);
这是一次插入 3 个表的单个 SQL 语句:
WITH genre AS (
insert into genre (name) values ('horror') returning id
),
book AS (
insert into book (name) values ('my scary book') returning id
)
insert into book_genre_rel (genre_id, book_id)
select genre.id, book.id from genre, book
现在这是一个 PostgreSQL 函数,可以在单个函数调用中完成所有操作:
CREATE OR REPLACE FUNCTION public.insert_book_and_genre(book_name text, genre_name text)
RETURNS void language SQL AS
$$
WITH genre AS (
insert into genre (name) values (genre_name) returning id
),
book AS (
insert into book (name) values (book_name) returning id
)
insert into book_genre_rel (genre_id, book_id)
select genre.id, book.id from genre, book
$$
这是一个测试它的示例:
select insert_book_and_genre('how to win friends by writing good sql', 'self-help')
现在,如果您已经创建了该函数(在 Supabase 查询编辑器中),那么您可以像这样从客户端调用它:
const { data, error } = await supabase
.rpc('insert_book_and_genre', {book_name: 'how I became a millionaire at age 3', genre_name: 'lifestyle'})
同样,我不推荐这种方法,至少不推荐这种方法genre
。您应该首先插入您的流派(它们可能不会改变)并将其简化为仅插入一个book
和一个book_genre_rel
记录。