我正在尝试在嵌套函数中编写触发器函数:
create or replace function get_book(val1 varchar, val2 varchar default null, val3 varchar default null)
returns table(books varchar, its_category varchar)
language plpgsql
as
$$
declare
fav_book varchar(255) := val1;
author_name varchar(255):= val2;
category_name varchar(255) := val3;
begin
if fav_book in(select book_name from books) then
return query
select b.book_name, ca.category
from books as b inner join categories as ca on b.category_id = ca.category_id
where ca.category= category_name;
else
begin
create or update function trigger_insertion()
returns void
language plpgsql
as $$
begin
insert into books(book_name)
values(fav_book);
create or update insert_category_author()
returns trigger
language plpgsql
as $$
declare
cat_id int;
auth_id int;
begin
if category_name in (select category from categories) then
select category_id into cat_id from categories where category_name = category
update books
set new.category_id = cat_id;
else
begin
insert into categories(category)
values(category_name);
select category_id into cat_id from categories where category_name = category;
update books
set new.category_id = cat_id;
end;
end if;
if author_name in (select author from authors) then
select author_id into auth_id from authors where author_name = author
update books
set new.author_id = auth_id;
else
begin
insert into authors(author)
values(author_name);
select author_id into auth_id from authors where author_name = author;
update books
set new.author_id = auth_id;
end;
end if;
end;
$$;
create trigger update_books_table
after insert on books
for each row execute procedure insert_category_author();
end;
return;
$$;
end;
end if;
end;
return;
$$;
我有三张桌子: Books 表的category_id 列引用category 表中的category_id 列, 和author_id引用author表中的author_id列和book_name列。
作者表有作者列,存储书籍的作者。 类别表有类别列,用于存储书籍的类别。
我想要实现的是检查 fav_book (用户给出的一本书)是否已存在于 books 表中的 book_name 列中,然后显示属于给定书籍同一类别的所有书籍。 如果 fav_book 不存在,则插入该书并触发函数 (insert_category_author) 该函数检查插入书籍的类别和作者,如果它们都已存在于表中(类别和作者),只需获取它们的 id 即可到变量中并更新 books 表的两列(category_id、author_id)。如果它们不存在,则插入它们并进行更新。
我只是想将所有函数嵌套在一个函数(get_book)中。 我不断收到错误,我知道代码中有很多问题,但我找不到实现我的想法的方法。
我得到的错误是:
ERROR: syntax error at or near "insert"
LINE 27: insert into books (book_name)
您的 PL/pgSQL 代码中似乎存在一些语法错误和问题。为了实现嵌套函数以及在单个函数中处理书籍、类别和作者的插入和更新逻辑的目标,您需要进行一些更正。下面是修改后的代码:
CREATE OR REPLACE FUNCTION get_book(val1 varchar, val2 varchar DEFAULT NULL, val3 varchar DEFAULT NULL)
RETURNS TABLE(books varchar, its_category varchar)
LANGUAGE plpgsql
AS
$$
DECLARE
fav_book varchar(255) := val1;
author_name varchar(255) := val2;
category_name varchar(255) := val3;
BEGIN
-- Check if the favorite book exists in the books table
IF EXISTS (SELECT 1 FROM books WHERE book_name = fav_book) THEN
-- If it exists, return the books in the same category
RETURN QUERY
SELECT b.book_name, ca.category
FROM books AS b
INNER JOIN categories AS ca ON b.category_id = ca.category_id
WHERE b.book_name = fav_book;
ELSE
-- If it doesn't exist, insert the book and handle categories and authors
INSERT INTO books (book_name)
VALUES (fav_book)
RETURNING book_name, its_category
INTO books, its_category;
-- Insert or update the category
PERFORM insert_category_author(fav_book, category_name, author_name);
RETURN NEXT;
END IF;
END;
$$;
-- This function handles category and author insertion/updating
CREATE OR REPLACE FUNCTION insert_category_author(book_name varchar, category_name varchar, author_name varchar)
RETURNS void
LANGUAGE plpgsql
AS
$$
DECLARE
cat_id INT;
auth_id INT;
BEGIN
-- Insert or update category
IF category_name IN (SELECT category FROM categories) THEN
SELECT category_id INTO cat_id FROM categories WHERE category = category_name;
ELSE
INSERT INTO categories (category)
VALUES (category_name)
RETURNING category_id INTO cat_id;
END IF;
-- Insert or update author
IF author_name IN (SELECT author FROM authors) THEN
SELECT author_id INTO auth_id FROM authors WHERE author = author_name;
ELSE
INSERT INTO authors (author)
VALUES (author_name)
RETURNING author_id INTO auth_id;
END IF;
-- Update the books table with category_id and author_id
UPDATE books
SET category_id = cat_id, author_id = auth_id
WHERE book_name = book_name;
END;
$$;
以下是一些关键更改和说明:
我在
get_book
函数中组合了检查书籍是否存在、插入书籍以及处理类别和作者的逻辑。
我创建了一个单独的
insert_category_author
函数来处理类别和作者的插入或更新。根据需要在 get_book
函数中调用此函数。
RETURNING
子句用于捕获插入或更新的值(例如,book_name、its_category)并将它们返回给get_book
函数中的调用者。
在
insert_category_author
函数中,我们首先检查类别和作者是否已经存在于各自的表中。如果他们这样做了,我们会检索他们的 ID;否则,我们插入它们并检索新的 ID。
最后,我们根据获取或插入的值使用适当的
books
和 category_id
更新 author_id
表。
请在您的 PostgreSQL 环境中测试此代码,并根据需要进一步调整它以满足您的特定表结构和要求。