Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Pgsql Novice > Problem with Tr...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 2 Topic 3105 of 3177
Post > Topic >>

Problem with Trigger

by dmies@[EMAIL PROTECTED] ("Don Mies (NIM)") May 5, 2008 at 04:41 PM

This is a multi-part message in MIME format.

------_=_NextPart_001_01C8AF09.8B0E09FA
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

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

=20

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.

=20

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)".

=20

I then defined the following function and trigger:

=20

CREATE OR REPLACE FUNCTION string_test()

    RETURNS trigger AS

    $$

        BEGIN

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

           RETURN NEW;

        END;

    $$

    LANGUAGE plpgsql;

=20

      CREATE TRIGGER check_string BEFORE INSERT OR UPDATE ON test_table

    FOR EACH ROW EXECUTE PROCEDURE string_test();

=20

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:

=20

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

INSERT 0 1

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

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

=20

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.

=20

So I have several questions:

=20

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] :=3D substr ( new.TG_ARGV[0], 1, TG_ARGV[1] );".  I have
not been able to find any syntax that will make that work.

=20

=20

Don

=20

=20


------_=_NextPart_001_01C8AF09.8B0E09FA
Content-Type: text/html;
	charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<html xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns=3D"http://www.w3.org/TR/REC-html40">

<head>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Dus-ascii">
<meta name=3DGenerator content=3D"Microsoft Word 11 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @[EMAIL PROTECTED]
 7 4 9 2 2 5 2 4 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:"Times New Roman";}
a:link, span.MsoHyperlink
	{color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;}
span.EmailStyle17
	{mso-style-type:personal-compose;
	font-family:Arial;
	color:windowtext;
	font-weight:normal;
	font-style:normal;
	text-decoration:none none;}
@[EMAIL PROTECTED]
 Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
	{page:Section1;}
 /* List Definitions */
 @[EMAIL PROTECTED]
 l0
	{mso-list-id:1100568514;
	mso-list-type:hybrid;
	mso-list-template-ids:-182268614 67698703 67698713 67698715 67698703 =
67698713 67698715 67698703 67698713 67698715;}
@[EMAIL PROTECTED]
 l0:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
ol
	{margin-bottom:0in;}
ul
	{margin-bottom:0in;}
-->
</style>

</head>

<body lang=3DEN-US link=3Dblue vlink=3Dpurple>

<div class=3DSection1>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>I&#8217;m currently using PostgreSQL 8.2.7 and having
trouble getting a trigger to work as I think it =
should.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>What I&#8217;m trying to accomplish is to truncate =
some
input strings if they are larger than the defined column in our =
database.&nbsp; 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.&nbsp;
Truncating the data is acceptable for the fields in =
question.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>For testing purposes I defined a new database called =
&#8220;test&#8221;
that contains a table called &#8220;test_table&#8221;.&nbsp; That table =
contains a
single column called &#8220;test_column&#8221; that is defined as =
&#8220;varchar(10)&#8221;.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>I then defined the following function and =
trigger:<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>CREATE OR REPLACE =
FUNCTION
string_test()<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp; =
RETURNS trigger AS<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp; =
$$<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; BEGIN<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEW.test_column :=3D
substr ( NEW.test_column, 1, 10 );<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETURN =
NEW;<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; END;<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp; =
$$<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp; =
LANGUAGE plpgsql;<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'><o:p>&nbsp;</o:p></span></=
font></p>

<p class=3DMsoNormal><font size=3D2 face=3DCourier><span =
style=3D'font-size:10.0pt;
font-family:Courier'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CREATE TRIGGER =
check_string BEFORE INSERT OR UPDATE
ON test_table<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>&nbsp;&nbsp;&nbsp; FOR =
EACH ROW EXECUTE PROCEDURE
string_test();<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'><o:p>&nbsp;</o:p></span></=
font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>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:<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>test=3D# INSERT INTO =
test_table
VALUES ('short');<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>INSERT 0 =
1<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>test=3D# INSERT INTO =
test_table
VALUES ('a string that is too long');<o:p></o:p></span></font></p>

<p class=3DMsoNormal style=3D'margin-left:.5in'><font size=3D2 =
face=3DCourier><span
style=3D'font-size:10.0pt;font-family:Courier'>ERROR:&nbsp; value too =
long for type
character varying(10)<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>I have put a &#8220;notice&#8221; 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.<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>So I have several =
questions:<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<ol style=3D'margin-top:0in' start=3D1 type=3D1>
 <li class=3DMsoNormal style=3D'mso-list:l0 level1 lfo1'><font size=3D2 =
face=3DArial><span
     style=3D'font-size:10.0pt;font-family:Arial'>Why doesn&#8217;t the =
above
     trigger and function work?&nbsp; It acts as though the database =
performs the
     validity checks on the input data BEFORE it calls the trigger =
function.<o:p></o:p></span></font></li>
 <li class=3DMsoNormal style=3D'mso-list:l0 level1 lfo1'><font size=3D2 =
face=3DArial><span
     style=3D'font-size:10.0pt;font-family:Arial'>Is there a better way =
to assure
     that the input data does not overflow a string =
column?<o:p></o:p></span></font></li>
 <li class=3DMsoNormal style=3D'mso-list:l0 level1 lfo1'><font size=3D2 =
face=3DArial><span
     style=3D'font-size:10.0pt;font-family:Arial'>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&#8217;t know exactly how large.) would =
it be
     reasonable to just redefine them as &#8220;varchar&#8221; or =
&#8220;text&#8221;
     with no upper limit?<o:p></o:p></span></font></li>
 <li class=3DMsoNormal style=3D'mso-list:l0 level1 lfo1'><font size=3D2 =
face=3DArial><span
     style=3D'font-size:10.0pt;font-family:Arial'>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.&nbsp; 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:&nbsp; record &quot;new&quot; has no field =
&quot;TG_ARGV[0]&quot;
     on the line that reads: &#8220;new.TG_ARGV[0] :=3D substr ( =
new.TG_ARGV[0],
     1, TG_ARGV[1] );&#8221;.&nbsp; I have not been able to find any =
syntax that
     will make that work.<o:p></o:p></span></font></li>
</ol>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></font></p>

<p class=3DMsoNormal><font size=3D3 face=3D"Times New Roman"><span =
style=3D'font-size:
12.0pt'>&nbsp;<o:p></o:p></span></font></p>

<p class=3DMsoNormal><font size=3D2 face=3DArial><span =
style=3D'font-size:10.0pt;
font-family:Arial'>Don</span></font><o:p></o:p></p>

<p class=3DMsoNormal><font size=3D3 face=3D"Times New Roman"><span =
style=3D'font-size:
12.0pt'>&nbsp;</span><o:p></o:p></font></p>

<p class=3DMsoNormal><font size=3D3 face=3D"Times New Roman"><span =
style=3D'font-size:
12.0pt'><o:p>&nbsp;</o:p></span></font></p>

</div>

</body>

</html>

------_=_NextPart_001_01C8AF09.8B0E09FA--
 




 2 Posts in Topic:
Problem with Trigger
dmies@[EMAIL PROTECTED]   2008-05-05 16:41:29 
Re: Problem with Trigger
tgl@[EMAIL PROTECTED] (T  2008-05-05 21:08:25 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan13V112 Thu Jul 24 7:18:05 CDT 2008.