Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

sql - Table as an argument of a PostgreSQL function

I'm trying to pass a table as an argument in a PostgreSQL function, and I can't find the right keyword (what should be instead of table in my code) in the first line :

CREATE FUNCTION test.fcttest(table)   
RETURNS SETOF test.out_table
AS $$
    INSERT INTO test.out_table /* obviously, the schema for this table is what it should be, an int column for A.id and a varchar(30) column for A.another_field */
        SELECT A.id, A.another_field
        FROM $1 A;
    SELECT A.id, A.another_field 
        FROM $1 A;
$$ 
LANGUAGE SQL;

Or maybe it just can't work like this ? If so, how should I do it ?

(Also, I guess there might also be SQL injection related issues with my function, but please ignore them for now, it's for a prototype in a secure environment so I don't have to worry about it for the moment. Or if you do address it, please do so in a separate part of your answer so I can understand what adresses what :) ).

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can not pass a table as such as a parameter, only the name of the table:

CREATE FUNCTION test.fcttest(tbl text) RETURNS SETOF test.out_table AS $$
BEGIN
  EXECUTE format('INSERT INTO test.out_table '
                   'SELECT id, another_field FROM %I', tbl);
  RETURN QUERY EXECUTE format('SELECT id, another_field FROM %I', tbl);
END;
$$ LANGUAGE plpgsql;

When passing a table name you need to execute a dynamic command. You can only do this in a plpgsql function. The use of the format() function with the %I modifier protects against SQL injection. The rows are returned using the RETURN NEXT QUERY phrase, again with a dynamic command.

Note that this logic both inserts a set of records into table test.out_table and then returns the same set of records. Not sure if that is what you really want.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...