Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

INSERT EXECUTE FORMAT Postgresql string

I want to create a function which will update the table.

I am trying to run it:

SELECT insert_function('asda', 1 ,1 , 'asd', 1)

But I get the error:

LINE 3 VALUES("asda","1","1","asd","1") column doesn't exist.

When I am trying rot run:

SELECT insert_function('1', 1 ,1 , '1', 1) zero-length delimited identifier at near """""""

LINE 3 VALUES(""1"","1","1",""1"","1") (^at the first item)

CREATE TABLE IF NOT EXISTS commits (
    id SERIAL PRIMARY KEY, 
    goo CHAR(64) NOT NULL, 
    foo INTEGER NOT NULL, 
    bla INTEGER NOT NULL, 
    ma CHAR(512) NOT NULL, 
    fgt INTEGER NOT NULL
);

CREATE OR REPLACE FUNCTION insert_function(goo char(64), foo INTEGER, bla INTEGER, ma CHAR(512), fgt INTEGER)
  RETURNS VOID AS
$func$
BEGIN
EXECUTE format('
   INSERT INTO commits 
   VALUES(%I,  %I,  %I,  %I, %I)', 
   goo , foo , bla , ma , fgt );

END
$func$ LANGUAGE plpgsql;

Could you please tell me how can I insert values? How can I write the function with EXECUTE format?

like image 920
user565447 Avatar asked Nov 20 '15 14:11

user565447


3 Answers

Specify column names and use using:

CREATE OR REPLACE FUNCTION insert_function(goo char(64), foo INTEGER,
                                           bla INTEGER, ma CHAR(512), fgt INTEGER)
RETURNS VOID AS
$func$
BEGIN
EXECUTE format('INSERT INTO commits(goo, foo, bla, ma, fgt)
                VALUES($1,$2,$3,$4,$5);') using goo, foo, bla, ma, fgt;

END
$func$ LANGUAGE plpgsql;

SqlFiddleDemo

like image 162
Lukasz Szozda Avatar answered Oct 06 '22 07:10

Lukasz Szozda


You have two problems:

When you want to insert into table, you have to specify all columns (even auto calculated columns), or if you don't want to specify all the columns names, you have to specify all of column value, even auto calcluated value too.

Concerning the format of your dynamic query, you should use %s instead of %I to interpolates the corresponding argument as a string which you want to achieve, and the %I escapes its argument as an SQL identifier which you don't want to.

So you can resolve your problem by replacing:

EXECUTE format('
   INSERT INTO commits 
   VALUES(%I,  %I,  %I,  %I, %I)', 
   goo , foo , bla , ma , fgt );

By

EXECUTE format('
   INSERT INTO commits 
   VALUES(DEFAULT, %L ,  %s ,  %s ,  %L , %s )', 
   goo , foo , bla , ma , fgt );
like image 34
Houari Avatar answered Oct 06 '22 05:10

Houari


The %I (uppercase i) formatter escapes the argument as an SQL identifier (docs here), which is not what you want. You should use %s in this case.

EXECUTE format('INSERT INTO commits VALUES(%L,  %s,  %s,  %L, %s)', goo , foo , bla , ma , fgt );
like image 44
Roberto Damian Alfonso Avatar answered Oct 06 '22 07:10

Roberto Damian Alfonso