Create global variable in Postgresql - postgresql

I am creating trigger for log table. In that trigger i want to store xuserno to log table. xuserno is a argument of all function
example:
CREATE OR REPLACE FUNCTION fn_consume(xmode text, xuserno integer)
RETURNS text AS
....
.....
.....
END;
Each table have this type of function. So how can i access the xuserno in my trigger. How can i create global variable for this purpose? or any other solution is have achive this?

It is possible to use transaction-local custom GUCs for this purpose but it's not usually a great idea.
In most cases it is preferable to just use an ON COMMIT DROP temporary table with a single row containing the value of interest.
See:
Passing user id to PostgreSQL triggers
How do you use script variables in PostgreSQL?

Related

Extracting a table name after installing a extension module in postgreSQL?

So the thing is I am developing a contrib module and want to capture table name inside that contrib module.
question:
Is there any way to capture a table name during create table or insert table?
I have seen some of the triggers but not able to make it (I don't think there is any create table trigger). In case it is possible tell me a way to achieve it.
I though of extracting meta-data using pg_class but not helping it seems because I have to give explicitly a rel-name (table name) in where clause
do you think any other way to achieve it? Please elaborate if any and please let me know.
Here is some example which will make you understand a bit about the things I want to achieve.
creating a table:
create table new_table(name varchar , new integer);
insert into new_table values('abcdefghijkl' , 5004);
create table new_table1(name1 varchar , new1 integer) ;
insert into new_table1 values('mnopqrst' , 5005);
creating extension:
create extension table_name-extract;
select extract_tablename();
So my extension should extract a table name, means I should know table name with the built-in datatype I have declared.
Here what I expect as a output:
select extract_tablename();
table-name datatype-name
new_table name new
new_table1 name1 new1
You don't really need an extension to track the execution of DDL statements.
For that you can use an event trigger
The manual also has an example on how to write an event trigger using PL/pgSQL
CREATE OR REPLACE FUNCTION snitch()
RETURNS event_trigger
AS $$
BEGIN
RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER snitch ON ddl_command_start
EXECUTE PROCEDURE snitch();
Inside the trigger function you would need to store the table name in some configuration table so that the information is not lost.
Of course you can package your trigger and "log table" (as a configuration table) into an extension if you want.
Another option is to enable DDL logging using
log_statement=ddl
in postgresql.conf - then you have all DDL statements in the Postgres logfile.

Triggers in postgresql

I am new to PostgreSQL and I am currently working on triggers but am stuck at one point.
I have two tables Student and Room.
Room id is the primary key in Room and foreign key in Student.
If I am inserting in Student, then it should check in Room whether the new data exist or not.
This is a foreign key check constraint. I hope anyone can help me with it
I dont know your code and I dont get the meaning, but I can answer generally.
In PostgreSQL a trigger is normally defined in two steps:
Define a trigger function using the CREATE FUNCTION
Bind this created trigger function to a table using CREATE TRIGGER
A trigger function is a common function, except that is has a return value type trigger (in addition, it does not take any arguments).
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS trigger
AS $$ ... $$;
binding:
CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW EXECUTE PROCEDURE trigger_function();
In addition, please also consult the excellent PG documentation at PostgreSQL 9.4 Triggers

How to add subset of fields from stored procedure to table variable?

Declare #tempTableVariable Table(
email varchar(50)
)
Insert INTO #tempTableVariable
EXEC GetData
select email
from #tempTableVariable
I get the following error:
"Column name or number of supplied values does not match table definition."
Is there a simple way of getting a subset from GetData without explicitly declaring all the fields in the table variable declaration?
If you don't have control over the GetData stored procedure, I don't think there is any way you can get around having to declare all the fields in your table variable.
If you can control GetData, you could add a parameter to it that when equal to 1 would returnt the results the way you want them, and otherwise would do what it does currently.
I'll mention it for the sake of completeness, but there are lots of other options besides INSERT EXEC. http://www.sommarskog.se/share_data.html is a great explanation of the options.

How to send values from the changed row to a trigger in postgres?

I want to create a trigger, somehow like this:
CREATE TRIGGER foo
AFTER UPDATE OR INSERT ON bar
FOR EACH ROW EXECUTE PROCEDURE baz(NEW.id);
The part with NEW.id doesn't work. How can I send values from the changed row (id for instance) to the trigger-function.
The trigger function (procedure) knows NEW and OLD automatically. No need to pass those as parameters.
Read more in the chapter on Trigger Procedures in the manual:
When a PL/pgSQL function is called as a trigger, several special
variables are created automatically in the top-level block. They are:
NEW
Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is NULL
in statement-level triggers and for DELETE operations.

Postgresql - Edit function signature

POSTGRESQL 8.4.3 - i created a function with this signature
CREATE OR REPLACE FUNCTION logcountforlasthour()
RETURNS SETOF record AS
realised i wanted to change it to this
CREATE OR REPLACE FUNCTION logcountforlasthour()
RETURNS TABLE(ip bigint, count bigint) record AS
but when i apply that change in the query tool it isnt accepted or rather it is accepted, there is no syntax error, but the text of the function has not been changed.
even if i run "DROP FUNCTION logcountforlasthour()" between edits the old syntax comes back
if i edit the body of the function, thats fine, it changes but not the signature
is there something i'm missing
thanks
From the PostgreSQL 8.4 manual:
To replace the current definition of
an existing function, use CREATE OR
REPLACE FUNCTION. It is not possible
to change the name or argument types
of a function this way (if you tried,
you would actually be creating a new,
distinct function). Also, CREATE OR
REPLACE FUNCTION will not let you
change the return type of an existing
function. To do that, you must drop
and recreate the function. (When using
OUT parameters, that means you cannot
change the names or types of any OUT
parameters except by dropping the
function.)
If you drop and then recreate a
function, the new function is not the
same entity as the old; you will have
to drop existing rules, views,
triggers, etc. that refer to the old
function. Use CREATE OR REPLACE
FUNCTION to change a function
definition without breaking objects
that refer to the function. Also,
ALTER FUNCTION can be used to change
most of the auxiliary properties of an
existing function.
The user that creates the function
becomes the owner of the function.
and also note:
...
PostgreSQL allows function overloading; that is, the same name can be used for several
different functions so long as they have distinct argument types.