execute sql inside plpgsql function

半腔热情 提交于 2019-12-14 03:08:35

问题


Using postgreSQL 9.1.9, I have some SQL requests like this:

 INSERT INTO "my_table" VALUES(10,'James','California');

Below a simplified table of the original names lookup table...

  names

  name_id      name
  ---          -----
  3            James

but in fact I don't have to enter (into "my_table") the text value provided by the SQL request (name of person, name of the state) but its corresponding ID located in another table (ex: names table)

So i was thinking on creating a trigger, calling a function that should execute the select SQL request and return the modified row to be inserted.

Is that possible?

CREATE FUNCTION insert_by_ID() RETURNS TRIGGER AS '

        BEGIN
            --Can we execute this query, store the result in a variable to be added
              to the NEW record?

            SELECT name_id from names where name=NEW.name;

                           --this request would be...
                           --SELECT name_id from names where name='James'     
          RETURN NEW;
        END;
        ' LANGUAGE plpgsql;

CREATE TRIGGER insert_info_ID
        BEFORE INSERT ON my_table
        FOR EACH ROW
        EXECUTE PROCEDURE insert_by_ID();

回答1:


My educated guess is you want a solution for the "SELECT or INSERT if not exists" problem.

I suggest you create a plpgsql function like this:

CREATE OR REPLACE FUNCTION f_name_id(_name text, OUT _name_id int) AS
$func$
BEGIN

LOOP
   BEGIN

   SELECT name_id FROM names WHERE name = _name FOR SHARE   -- lock!
   INTO  _name_id;

   IF NOT FOUND THEN
      INSERT INTO names (name) VALUES (_name) RETURNING name_id
      INTO  _name_id;
   END IF;

   EXCEPTION WHEN UNIQUE_VIOLATION THEN      -- inserted concurrently!
      RAISE NOTICE 'It actually happened!';  -- hardly ever happens
   END;

   EXIT WHEN _name_id IS NOT NULL;           -- else try again
END LOOP;

END
$func$ LANGUAGE plpgsql;

This is a simple version of (more explanation and links over there):
Is SELECT or INSERT in a function prone to race conditions?

INSERT

Then your INSERT statement can look like this:

INSERT INTO my_table(my_table_id, name_id, state) -- always with column list
VALUES (10, f_name_id('James'), 'California');


来源:https://stackoverflow.com/questions/23657948/execute-sql-inside-plpgsql-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!