【问题标题】:Postgres SQL function and trigger to insert record in another tablePostgresql函数和触发器在另一个表中插入记录
【发布时间】:2020-07-06 15:08:14
【问题描述】:

我需要帮助来完成以下要求:

  • [x] Profile 带有列的表 id, username, ...
  • [x] Comment 带有列的表 id, content, ...
  • [x] CommentReference 带有列的表 id, profile_id, comment_id, ...

创建新评论时,插入前:

  • [ ] 检查NEW.content 是否引用了用户名,例如@someusername
  • [ ] 检查配置文件表中是否存在每个引用
  • [ ] 对于存在的引用,插入到CommentReferences 配置文件和评论

目前,我有以下代码:

PS:以下代码有错误,我需要帮助修复它。我正在使用 postgres 版本 12。

CREATE FUNCTION create_comment_usernames_references()
RETURNS trigger AS $$
DECLARE usernames TEXT[];
DECLARE username TEXT;
DECLARE profile_id TEXT; -- profile_id is of type uuid, is it correct to use TEXT here?
BEGIN
  -- verify if there are usernames in the comment.content with the username regex
  SELECT DISTINCT(
    regexp_matches(
      NEW.content,
      '@(([a-z0-9]*((?<=[a-z0-9])[-|_|\.](?=[a-z0-9]))[a-z0-9]*)*|[a-z0-9]*)',
      'g'
    )
  )[1]
  INTO usernames;

  FOREACH username IN ARRAY usernames LOOP
    SELECT (SELECT id FROM "public"."Profile" WHERE "username" = username) INTO profile_id
    INSERT INTO "public"."CommentReference" (comment_id, profile_id) VALUES (NEW.id, profile_id);
  END LOOP;

  -- return nothing
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER create_comment_usernames_references_trigger
  BEFORE INSERT OR UPDATE ON "public"."Comment"
  FOR EACH ROW
  EXECUTE PROCEDURE create_comment_usernames_references();

【问题讨论】:

  • 你看到了什么错误?
  • @kofemann 我在 hasura 控制台中运行它,错误输出不是很有帮助,而且我不是 SQL 专家,它只是说在INSERT附近或处有一些错误@
  • 第一个猜测是在插入之前检查 SELECT 是否返回了一些值,例如 IF FOUND THEN....*跨度>
  • @kofemann 我认为profile _id 存在一些问题,它是表格格式,所以我想我需要在插入之前从profile_id 中提取id,但不确定这个怎么做。另外,我当然需要添加 IF 语句。

标签: sql postgresql postgresql-12


【解决方案1】:

自己解决。

最终代码:

CREATE OR REPLACE FUNCTION find_profile_ids_by_usernames_in_text(_value TEXT)
    RETURNS TABLE (profile_id   uuid) AS
$func$
BEGIN
    RETURN QUERY
    SELECT
        id
    FROM
        "public"."Profile"
    WHERE
        username IN (
            SELECT DISTINCT(
            regexp_matches(
                _value,
                '@(([a-z0-9]*((?<=[a-z0-9])[-|_|\.](?=[a-z0-9]))[a-z0-9]*)*|[a-z0-9]*)',
                'g')
            )[1]
        );
END
$func$  LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION create_comment_reference(_comment_id UUID, _content TEXT)
RETURNS integer AS $$
DECLARE
    row RECORD;
BEGIN
    FOR row IN
       SELECT * FROM find_profile_ids_by_usernames_in_text(_content)
    LOOP
        INSERT INTO
            "public"."CommentReference" (comment_id, profile_id)
        VALUES
            (_comment_id, row.profile_id)
        ON CONFLICT DO NOTHING;
    END LOOP;
    RETURN 1;
END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION create_comment_reference_trigger_func()
RETURNS trigger AS $$
DECLARE someval integer;
BEGIN
  select * from create_comment_reference(NEW.id, NEW.content) into someval;
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;


CREATE TRIGGER create_comment_usernames_references_trigger
  AFTER INSERT OR UPDATE ON "public"."Comment"
  FOR EACH ROW
  EXECUTE PROCEDURE create_comment_reference_trigger_func();

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多