Skip to main content
markup, format, denoise, links, fiddle
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   FOR _tbl_in IN EXECUTE
      format('SELECT * FROM %s', pg_typeof(_tbl_in))
   LOOP
      -- do something with record

      EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
      USING _tbl_in;
   END LOOP;
END
$func$;

t and t1 being the tables with identical schema.

Note that the The polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SOThis related answer on SO explains the solution. Provides a workaround for older versions, too.

The value of the first parameter is discardeddiscarded. UseJust use NULL.

Consider this related answer on SO with more detailsthis related answer on SO with more details. The most interesting part being the last chapter Various complete table types"Various complete table types".

SQL Fiddle demo.db<>fiddle here
Old sqlfiddle

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void
  LANGUAGE plpgsql AS
$func$
BEGIN
   FOR _tbl_in IN EXECUTE
      format('SELECT * FROM %s', pg_typeof(_tbl_in))
   LOOP
      -- do something with record

      EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
      USING _tbl_in;
   END LOOP;
END
$func$;

t and t1 being tables with identical schema.

The polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

The value of the first parameter is discarded. Just use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter "Various complete table types".

db<>fiddle here
Old sqlfiddle

Commonmark migration
Source Link

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

###Major ingredients

Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

###Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

###Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SOThis related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more detailsthis related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

###Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

There is a solution with just PL/pgSQL. Simple and elegant, too. Pretty advanced stuff, though.
Requires Postgres 9.0 or later (workaround for older versions possible).

CREATE OR REPLACE FUNCTION gesio(_tbl_in anyelement, _tbl_out regclass)
  RETURNS void AS
$func$
BEGIN

FOR _tbl_in IN EXECUTE
   format('SELECT * FROM %s', pg_typeof(_tbl_in))
LOOP
   -- do something with record

   EXECUTE format('INSERT INTO %s SELECT $1.*', _tbl_out)
   USING _tbl_in;
END LOOP;

END
$func$  LANGUAGE plpgsql;

Call (important!):

SELECT gesio(NULL::t, 't1');

t and t1 being the tables with identical schema.

Note that the polymorphic parameter (anyelement) is only needed if you need it's value or data type for the computation in the function body. Else you can simplify like demonstrated in this later answer:

###Major ingredients

An obstacle to overcome is that variables inside the function cannot be defined as polymorphic type anyelement (yet). This related answer on SO explains the solution. Provides a workaround for older versions, too.

I am handing in a NULL value of type t, which serves three purposes:

  • Provide table name.
  • Provide table type.
  • Serve as loop variable.

The value of the first parameter is discarded. Use NULL.

Consider this related answer on SO with more details. The most interesting part being the last chapter Various complete table types.

SQL Fiddle demo.

If your computations are not too sophisticated, you may be able to replace the loop with a single dynamic SQL statement, which is typically faster.

replaced http://dba.stackexchange.com/ with https://dba.stackexchange.com/
Source Link
Loading
add note and link
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
Fix syntax for pg 9.3+, update fiddle, trim noise, clean up
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
VALUES is simpler, improve format, add link
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
clean up, trim noise
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
added 73 characters in body
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading
Source Link
Erwin Brandstetter
  • 182.2k
  • 28
  • 457
  • 620
Loading