Thread: How do I insert a record into a table?
I want to write a query like: INSERT INTO table SELECT func(args); where func is defined as: CREATE OR REPLACE FUNCTION func(args) RETURNS table AS $_$ ... $_$ LANGUAGE plpgsql; Unfortunately, when I try to do this, I get: ERROR: column "first_column" is of type integer but expression is of type record I get this error even if I list the columns: INSTER INTO table(first_column, second_column, ...) .... So how do I take a record returned from a function, and insert it as a row into a table? Brian
On Jun 1, 2007, at 13:31 , Brian Hurt wrote: > > I want to write a query like: > > INSERT INTO table SELECT func(args); I think you might want to try something along the lines of INSERT INTO table (col1, col2, col3) SELECT col1, col2, col3 FROM func(args); Then again, you could wrap the whole insert into the function: CREATE FUNCTION func(args) RETURNS VOID LANGUAGE plpgsql AS $_$ -- ... INSERT INTO table (col1, col2, col3)... $_$; then SELECT func(args); to call the function. Michael Glaesemann grzm seespotcode net
--- Brian Hurt <bhurt@janestcapital.com> wrote: > > I want to write a query like: > INSERT INTO table SELECT func(args); > where func is defined as: > CREATE OR REPLACE FUNCTION func(args) > RETURNS table > AS $_$ > ... > $_$ LANGUAGE plpgsql; > Unfortunately, when I try to do this, I get: > ERROR: column "first_column" is of type integer but expression is of > type record > I get this error even if I list the columns: > INSTER INTO table(first_column, second_column, ...) .... > So how do I take a record returned from a function, and insert it as a > row into a table? What does a select * from table; look like? What does a select * from func(args); look like? Regards, Richard Broersma Jr.
Brian Hurt wrote: > > I want to write a query like: > > INSERT INTO table SELECT func(args); > > where func is defined as: > > CREATE OR REPLACE FUNCTION func(args) > RETURNS table > AS $_$ > ... > $_$ LANGUAGE plpgsql; > > Unfortunately, when I try to do this, I get: > > ERROR: column "first_column" is of type integer but expression is of > type record > If I understand what you are trying to do then one suggestion would be to execute everything inside the function. SELECT * FROM my_function(args); --(args is an array that looks like this: '{tablename,column1,column2,...}' then: CREATE OR REPLACE FUNCTION my_function(_varchar) RETURNS int4 AS $BODY$ DECLARE variables alias for $1; BEGIN EXECUTE 'INSERT INTO'||variables[0]||' VALUES('||variables[i]||','||variables[2]||', '|| ... ||')'; RETURN 1; END $BODY$ LANGUAGE 'plpgsql' VOLATILE;
Richard Broersma Jr wrote:
The same. Note that I defined func to return type table.--- Brian Hurt <bhurt@janestcapital.com> wrote:I want to write a query like: INSERT INTO table SELECT func(args); where func is defined as: CREATE OR REPLACE FUNCTION func(args) RETURNS table AS $_$ ... $_$ LANGUAGE plpgsql; Unfortunately, when I try to do this, I get: ERROR: column "first_column" is of type integer but expression is of type record I get this error even if I list the columns: INSTER INTO table(first_column, second_column, ...) .... So how do I take a record returned from a function, and insert it as a row into a table?What does a select * from table; look like? What does a select * from func(args); look like?
Michael Glaesemann wrote: > > On Jun 1, 2007, at 13:31 , Brian Hurt wrote: > >> >> I want to write a query like: >> >> INSERT INTO table SELECT func(args); > > > I think you might want to try something along the lines of > INSERT INTO table (col1, col2, col3) > SELECT col1, col2, col3 > FROM func(args); What I'm really trying to do is to write a rule of the form: CREATE OR REPLACE VIEW table AS SELECT * FROM real_table; CREATE OR REPLACE RULE myrule AS ON INSERT TO table DO INSTEAD INSERT INTO real_table VALUES (func(NEW)); Basically to require all inserts to be "cleaned" by func. The reason for this is we're trying to keep a modification history of the table. Insert is the simple case- the update and delete rules will be much more interesting. > > Then again, you could wrap the whole insert into the function: > > CREATE FUNCTION func(args) > RETURNS VOID > LANGUAGE plpgsql AS $_$ > -- ... > INSERT INTO table (col1, col2, col3)... > $_$; > > then SELECT func(args); to call the function. > This is the current solution I'm going with. The main problem I have with this is stylistic- it changes the result psql displays from an insert response to a select response. Brian
On Jun 1, 2007, at 14:54 , Brian Hurt wrote: > This is the current solution I'm going with. The main problem I > have with this is stylistic- it changes the result psql displays > from an insert response to a select response. If you'd like, you could throw in a RAISE NOTICE (or other level) so you get some other information. Michael Glaesemann grzm seespotcode net
Michael Glaesemann wrote: > > On Jun 1, 2007, at 14:54 , Brian Hurt wrote: > >> This is the current solution I'm going with. The main problem I have >> with this is stylistic- it changes the result psql displays from an >> insert response to a select response. > > > If you'd like, you could throw in a RAISE NOTICE (or other level) so > you get some other information. If I just do an insert into the table, I see: bhurt_dev=# INSERT INTO test1(id, name) VALUES (1, 'foo'); INSERT 0 1 bhurt_dev=# But if I define: CREATE FUNCTION insert_test1(p_id INT, p_name VARCHAR) RETURNS VOID AS $_$ BEGIN INSERT INTO test1(id, name) VALUES(p_id, p_name); END $_$ LANGUAGE plpgsql; CREATE VIEW view1 AS SELECT * FROM test1; CREATE RULE rule1 AS ON INSERT TO view1 DO INSTEAD SELECT insert_test1(NEW.id, NEW.name); and then do: bhurt_dev=# INSERT INTO view1(id, name) VALUES (2, 'bar'); insert_test1 -------------- (1 row) bhurt_dev=# See the difference? It's stylistic, and doesn't actually change anything. Brian
On Jun 1, 2007, at 15:20 , Brian Hurt wrote: > See the difference? Yes, I saw/see the difference. I was trying to suggest a way for you to get additional information. As you're doing a SELECT rather than an INSERT, of course the server response is going to be different. Just trying to give you options :) Michael Glaesemann grzm seespotcode net