472,374 Members | 1,377 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,374 software developers and data experts.

Update inside (Insert) Trigger and Unique constraint...

I'm trying to build a table that will store a history of records
by enumerating the records. I want the newest record to always
be number ZERO, so I created a trigger on my table to handle the
assignment of version numbers:

CREATE TRIGGER "trg_audio_file_insert" BEFORE INSERT
ON "public"."audio_file" FOR EACH ROW
EXECUTE PROCEDURE "public"."trg_audio_file_insert"();

My trigger function looks like this...

CREATE FUNCTION "public"."trg_audio_file_insert" () RETURNS trigger AS'
BEGIN
...
/* rollback the version number of previous versions of this
audio_id */
UPDATE audio_file SET
afile_version = afile_version + 1
WHERE acct_id = NEW.acct_id
AND audio_id = NEW.audio_id;

/* newly inserted row is always the latest version ''0'' */
NEW.afile_version := 0;

...
/* yeah, that worked */
RETURN NEW;
END;
'LANGUAGE 'plpgsql';

There exists a unique constraint on the 'the audio_id / audio_version'
columns. However, when I insert records into this table, I'm getting an
error like:

duplicate key violates unique constraint "idx_audio_file_id_version"
CONTEXT: PL/pgSQL function "trg_audio_file_insert" line 18 at SQL
statement

I don't understand WHY there could be a violation of the constraint when
I clearly asked for the update to be performed prior to the assigning of
NEW.afile_version := 0;. Yes, there exist two records with my acct_id and
audio_id with versions 0 and 1 already. The update should roll them to
1 and 2 then the insert at 0 should be unique still.

Why isn't this working? What's the deal with ordering when it comes to
triggers? Is the update not performed when I tell it to?

Dante


---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 22 '05 #1
2 6459
NEVERMIND... This is not a trigger problem. It's a unique
constraint problem... If I have a unique constraint on
a column like 'afile_version', and want to do an update on
that column to add one to each number, is there a way to
add an 'ORDER BY' to the update?

UPDATE audio_file SET
afile_version = afile_version + 1
ORDER BY afile_version DESC;

???

The problem is that with

0 --> 1
1 --> 2
2 --> 3
insert 0

The update would update 0 to 1 and hit a constraint violation.
I needed to start from the bottom and work my way up...

2 --> 3
1 --> 2
0 --> 1
insert 0

So, I wrote a FOR LOOP like this:

FOR my_rec IN
SELECT afile_id
FROM audio_file
ORDER BY afile_version DESC
LOOP
/* roll back the version... */
UPDATE audio_file SET
afile_version = afile_version + 1
WHERE afile_id = my_rec.afile_id;
END LOOP;

And that does the trick, but I guess I might also be able
to do something like this?:

UPDATE audio_file SET
afile_version = afile_version + 1
WHERE afile_id IN (
SELECT afile_id
FROM audio_file
ORDER BY afile_version DESC
);

Yeah, so I guess I figured this out on my own, but from a
performance viewpoint, would the second method be better
.... or the first? Does it matter?

Dante


D. Dante Lorenso wrote:
I'm trying to build a table that will store a history of records
by enumerating the records. I want the newest record to always
be number ZERO, so I created a trigger on my table to handle the
assignment of version numbers:

CREATE TRIGGER "trg_audio_file_insert" BEFORE INSERT
ON "public"."audio_file" FOR EACH ROW
EXECUTE PROCEDURE "public"."trg_audio_file_insert"();

My trigger function looks like this...

CREATE FUNCTION "public"."trg_audio_file_insert" () RETURNS trigger
AS'
BEGIN
...
/* rollback the version number of previous versions of this
audio_id */
UPDATE audio_file SET
afile_version = afile_version + 1
WHERE acct_id = NEW.acct_id
AND audio_id = NEW.audio_id;
/* newly inserted row is always the latest version ''0'' */
NEW.afile_version := 0;

...
/* yeah, that worked */
RETURN NEW;
END;
'LANGUAGE 'plpgsql';

There exists a unique constraint on the 'the audio_id / audio_version'
columns. However, when I insert records into this table, I'm getting an
error like:

duplicate key violates unique constraint "idx_audio_file_id_version"
CONTEXT: PL/pgSQL function "trg_audio_file_insert" line 18 at SQL
statement

I don't understand WHY there could be a violation of the constraint when
I clearly asked for the update to be performed prior to the assigning of
NEW.afile_version := 0;. Yes, there exist two records with my acct_id
and
audio_id with versions 0 and 1 already. The update should roll them to
1 and 2 then the insert at 0 should be unique still.

Why isn't this working? What's the deal with ordering when it comes to
triggers? Is the update not performed when I tell it to?

Dante


---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings



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

http://www.postgresql.org/docs/faqs/FAQ.html

Nov 22 '05 #2
On Wednesday 21 January 2004 20:12, D. Dante Lorenso wrote:
NEVERMIND... This is not a trigger problem. It's a unique
constraint problem... If I have a unique constraint on
a column like 'afile_version', and want to do an update on
that column to add one to each number, is there a way to
add an 'ORDER BY' to the update? [snip] FOR my_rec IN
SELECT afile_id
FROM audio_file
ORDER BY afile_version DESC
LOOP
/* roll back the version... */
UPDATE audio_file SET
afile_version = afile_version + 1
WHERE afile_id = my_rec.afile_id;
END LOOP;
This was mentioned in the last couple of weeks on one of the lists - don't
know which. Someone suggested doing UPDATE ...version=-version followed by
UPDATE ...version=(-version)+1
And that does the trick, but I guess I might also be able
to do something like this?:
Nope - or rather, if it does work I think it's down to chance.
UPDATE audio_file SET
afile_version = afile_version + 1
WHERE afile_id IN (
SELECT afile_id
FROM audio_file
ORDER BY afile_version DESC
);


PS - this is really a bug, but it doesn't seem to bite very often, and there
are work-arounds, so it hasn't reached the top of any developer's list yet.

--
Richard Huxton
Archonet Ltd

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 22 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Jason | last post by:
I have a table that matches up Securities and Exchanges. Individual securities can belong on multiple exchanges. One of the columns, named PrimaryExchangeFlag, indicates if a particular exchange is...
2
by: MAS | last post by:
Below is a simple UPDATE that I have to perform on a table that has about 2.5 million rows (about 4 million in production) This query runs for an enourmous amount of time (over 1 hour). Both the...
8
by: Jan van Veldhuizen | last post by:
The UPDATE table FROM syntax is not supported by Oracle. I am looking for a syntax that is understood by both Oracle and SqlServer. Example: Table1: id name city ...
3
by: takilroy | last post by:
Hi, Does anyone know of a simple way to do this? I want to create an insert trigger for a table and if the record already exists based on some criteria, I want to update the table with the...
1
by: Derek Erb | last post by:
SQL Server 2000 : I have a series of tables which all have the same structure. When any of these tables are modified I need to syncrhonise all of those modifications with one other table wich is a...
8
by: Paul Reddin | last post by:
Hi, We have been having many issues with unique constraints and we seem to have boiled it down to the equivalent of the following very simple scenario... given a table with a unqiue...
5
by: wpellett | last post by:
I can not get the SQL compiler to rewrite my SQL UPDATE statement to include columns being SET in a Stored Procedure being called from a BEFORE UPDATE trigger. Example: create table...
13
by: dennis | last post by:
Hello, I'm having trouble solving the following problem with DB2 UDB 8.2. I need to create a trigger that performs certain extra constraint validations (temporal uniqueness). One of the tables...
3
by: Wojto | last post by:
Hi there! I need to write a trigger that will check referential integrity of my data. I have few FOREIGN KEY constraints but, as You probably konow, the cannot be deferred (in the meaning of SQL...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
2
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...
0
DizelArs
by: DizelArs | last post by:
Hi all) Faced with a problem, element.click() event doesn't work in Safari browser. Tried various tricks like emulating touch event through a function: let clickEvent = new Event('click', {...
0
by: F22F35 | last post by:
I am a newbie to Access (most programming for that matter). I need help in creating an Access database that keeps the history of each user in a database. For example, a user might have lesson 1 sent...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.