Re: [SQL] Advice for generalizing trigger functions

2007-12-28 Thread Marcin Stępnicki

Dnia 25-12-2007, Wt o godzinie 16:20 -0800, Richard Broersma Jr pisze:
> I've created quite a few functions that log modifications to various history 
> tables. 
> (the history table has the same name as the base table but is prefixed by the 
> 'History.' schema.)
>  The only difference between functions I can find is the table name.
> 
> Is there any way to generalize these myriad of functions into one?
> 

Maybe just try http://pgfoundry.org/projects/audittrail2/ ?

Or there's something my friend wrote some time ago (I use audittrail
now, but I think that this function works with reasonably recent
PostgreSQL releases). Sorry for Polish comments, I've just taken it out
from old repository.


CREATE OR REPLACE FUNCTION create_history_table(text, text)
  RETURNS text AS
$BODY$
DECLARE
tabela ALIAS FOR $1;
query TEXT;
fields RECORD;
grupa ALIAS FOR $2;
BEGIN
query := '';

-- poczatek definicji zapytania tworzacego historie
query := 'CREATE TABLE "H' || tabela || '"(\r\n';

-- petelka wyciagajaca pola tabeli do ktorej tworzona jest historia
FOR fields IN 
SELECT a.attname AS name,
   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || fields.name || ' ' || fields.type || ',\r\n';

END LOOP; 

-- doklejenie pol dotyczacych historii
query := query || 'log_usename text default current_user, '
   || 'log_time timestamp default now(), '
   || 'log_event text default  '
   || ');\r\n';

-- ustawienie uprawnien do zapisu i odczytu z tabeli historii
query := query || 'GRANT SELECT, INSERT ON "H' || tabela || '" TO GROUP "' 
|| grupa || '";\r\n';

--EXECUTE query;
--query := '';
-- definicja funkcji dla triggera historii
query := query || 'CREATE FUNCTION "H' || tabela || '"() RETURNS trigger 
AS\r\n'
   || '$$\r\n'
   || 'begin\r\n'
   || 'if ( tg_op = ''INSERT'' ) then\r\n'
   || 'INSERT INTO "H' || tabela || '" (\r\n';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || '' || fields.name || ', \r\n';

END LOOP; 

query := query || 'log_event ) VALUES (\r\n';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || 'NEW.' || fields.name || ', \r\n';

END LOOP; 

query := query || '''I'');\r\n';

query := query || 'end if;\r\n'
   || 'if tg_op = ''UPDATE'' then\r\n'
   || 'if OLD.id != NEW.id then\r\n'
   || 'UPDATE "H' || tabela || '" SET id = NEW.id WHERE 
id = OLD.id;\r\n'
   || 'end if;\r\n'
   || 'INSERT INTO "H' || tabela || '"(\r\n';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || '' || fields.name || ', \r\n';

END LOOP; 

query := query || 'log_event ) VALUES (\r\n';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || 'NEW.' || fields.name || ', \r\n';

END LOOP; 

query := query || '''U'');\r\n';

query := query || 'end if;\r\n'
   || 'if tg_op = ''DELETE'' then\r\n'
   || 'INSERT INTO "H' || tabela || '"(';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attnum > 0
LOOP

query := query || '' || fields.name || ', \r\n';

END LOOP; 

query := query || 'log_event ) VALUES (\r\n';

FOR fields IN 
SELECT a.attname AS name
--   format_type(a.atttypid, a.atttypmod) AS type
  FROM pg_attribute a 
 WHERE a.attrelid = ( SELECT oid FROM pg_class WHERE relname = tabela ) 
   AND a.attn

[SQL] PL/pgsql: function passing argument to IN operator

2007-12-28 Thread Daniel Myers
Hello list,
   I'm trying to write a function that uses one of its arguments as
an input to an IN operator in a WHERE clause. I.e., something like:

-- ids are actually integers
CREATE FUNCTION foo(ids SOMETYPE) RETURNS [whatever] AS $$
BEGIN
   SELECT id, [other stuff] FROM table WHERE [other conditions] AND
id IN (ids);
   RETURN;
END
$$ plpgsql

I had wanted to avoid using the EXECUTE statement and dynamically
creating the query string, because 1) I'd rather not recompile the
query each time and 2) I'm doing a SELECT INTO, which apparently
doesn't work with EXECUTE.

Can anyone help me out?

Thanks,
Daniel

P.S.: Sorry if capitalizing SQL keywords is bad list etiquette...

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [SQL] PL/pgsql: function passing argument to IN operator

2007-12-28 Thread Pavel Stehule
Hello

it has sense only for array type

so you can try:
create replace function foo(anyarray)
returns bool as $$
begin
  return (select 1 = any($1));
end ; $$ language plpgsql;


postgres=# select foo(array[1,2,3]);
 foo
-
 t
(1 row)

postgres=# select foo(array[2,3]);
 foo
-
 f
(1 row)

Regards
Pavel Stehule

On 29/12/2007, Daniel Myers <[EMAIL PROTECTED]> wrote:
> Hello list,
>I'm trying to write a function that uses one of its arguments as
> an input to an IN operator in a WHERE clause. I.e., something like:
>
> -- ids are actually integers
> CREATE FUNCTION foo(ids SOMETYPE) RETURNS [whatever] AS $$
> BEGIN
>SELECT id, [other stuff] FROM table WHERE [other conditions] AND
> id IN (ids);
>RETURN;
> END
> $$ plpgsql
>
> I had wanted to avoid using the EXECUTE statement and dynamically
> creating the query string, because 1) I'd rather not recompile the
> query each time and 2) I'm doing a SELECT INTO, which apparently
> doesn't work with EXECUTE.
>
> Can anyone help me out?
>
> Thanks,
> Daniel
>
> P.S.: Sorry if capitalizing SQL keywords is bad list etiquette...
>
> ---(end of broadcast)---
> TIP 3: Have you checked our extensive FAQ?
>
>http://www.postgresql.org/docs/faq
>

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq