Unix Technical Forum

Problem with Trigger

This is a discussion on Problem with Trigger within the pgsql Novice forums, part of the PostgreSQL category; --> I'm currently using PostgreSQL 8.2.7 and having trouble getting a trigger to work as I think it should. What ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > pgsql Novice

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 05-07-2008, 11:18 AM
Don Mies
 
Posts: n/a
Default Problem with Trigger

I'm currently using PostgreSQL 8.2.7 and having trouble getting a
trigger to work as I think it should.



What I'm trying to accomplish is to truncate some input strings if they
are larger than the defined column in our database. For a number of
reasons, this will be difficult to do in the code that is calling
PostgreSQL so it is desirable to do via a trigger in the database
itself. Truncating the data is acceptable for the fields in question.



For testing purposes I defined a new database called "test" that
contains a table called "test_table". That table contains a single
column called "test_column" that is defined as "varchar(10)".



I then defined the following function and trigger:



CREATE OR REPLACE FUNCTION string_test()

RETURNS trigger AS

$$

BEGIN

NEW.test_column := substr ( NEW.test_column, 1, 10 );

RETURN NEW;

END;

$$

LANGUAGE plpgsql;



CREATE TRIGGER check_string BEFORE INSERT OR UPDATE ON test_table

FOR EACH ROW EXECUTE PROCEDURE string_test();



The trigger works fine if the input string is less than or equal to the
column size (10 bytes) but if the input string is larger, the trigger
never fires:



test=# INSERT INTO test_table VALUES ('short');

INSERT 0 1

test=# INSERT INTO test_table VALUES ('a string that is too long');

ERROR: value too long for type character varying(10)



I have put a "notice" command in the function to verify that the
function does not get called in the second case but it does get called
in the first.



So I have several questions:



1. Why doesn't the above trigger and function work? It acts as
though the database performs the validity checks on the input data
BEFORE it calls the trigger function.
2. Is there a better way to assure that the input data does not
overflow a string column?
3. Since the columns that I need to do this to are all somewhat
controlled (i.e. They will never be extremely large, I just don't know
exactly how large.) would it be reasonable to just redefine them as
"varchar" or "text" with no upper limit?
4. If I could make the above code work, it would be highly
desireable to write only 1 function that could be called from multiple
triggers. However, when I tried to change the code to accept a column
name and length as input arguments, I got an error saying that ERROR:
record "new" has no field "TG_ARGV[0]" on the line that reads:
"new.TG_ARGV[0] := substr ( new.TG_ARGV[0], 1, TG_ARGV[1] );". I have
not been able to find any syntax that will make that work.





Don






Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 05-07-2008, 11:18 AM
Tom Lane
 
Posts: n/a
Default Re: Problem with Trigger

"Don Mies (NIM)" <dmies@networksinmotion.com> writes:
> What I'm trying to accomplish is to truncate some input strings if they
> are larger than the defined column in our database.


This cannot work because the value gets put into the tuple --- and hence
cast to the defined column type --- before the trigger can ever fire.

If you wanted to define the column as just "text", and put 100% reliance
on the trigger to enforce the length limit, then it would work.

> 3. Since the columns that I need to do this to are all somewhat
> controlled (i.e. They will never be extremely large, I just don't know
> exactly how large.) would it be reasonable to just redefine them as
> "varchar" or "text" with no upper limit?


Probably. I think the standard's focus on "varchar(N)" is a hangover
from the days of 80-column punched cards. In almost every modern-day
app, whatever value they're using for N is just picked out of the air
and has no business-logic justification whatsoever. Unless you can
point to a concrete application-driven reason why you need a limit of
exactly N, I think you should be using text.

> 4. If I could make the above code work, it would be highly
> desireable to write only 1 function that could be called from multiple
> triggers.


Not going to happen in plpgsql --- it has no real support for
run-time-determined column names. You could make it work in one of the
other PLs. I still question the need for it at all, though.

regards, tom lane

--
Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:48 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com