Обсуждение: unique key problem on update

Поиск
Список
Период
Сортировка

unique key problem on update

От
Gary Stainburn
Дата:
Hi folks.

I've got the table and data shown below. 

I want to add a new page after page 2 so I try to increase the sequence number 
of each row from page 3 onwards to make space in the sequence for the new 
record. However, I get duplicate key errors when I try. Can anyone suggest 
how I get round this.

Also, the final version will be put onto a WordPress web site which means I 
will have to port it to MYSQL which I don't know, so any solution that will 
work with both systems would be a great help.

Ta

Gary


stainburn=# \d skills_pages                                   Table "public.skills_pages"  Column    |         Type
    |                          Modifiers                           
 
-------------+-----------------------+--------------------------------------------------------------sp_id       |
integer              | not null default 
 
nextval('skills_pages_sp_id_seq'::regclass)sp_sequence | integer               | not nullsp_title    | character
varying(80)| sp_narative | text                  | 
 
Indexes:   "skills_pages_pkey" PRIMARY KEY, btree (sp_id)   "skills_pages_sequence" UNIQUE, btree (sp_sequence)

stainburn=# select * from skills_pages;sp_id | sp_sequence |     sp_title     | sp_narative 
-------+-------------+------------------+-------------    1 |          10 | Departments      |     2 |          20 |
InterestGroups  |     3 |          30 | Customer Focused |     4 |          40 | Business Roles   |     5 |          50
|Commercial       |     6 |          60 | People Oriented  |     7 |          70 | Engineering      | 
 
(7 rows)

stainburn=# update skills_pages set sp_sequence=sp_sequence+10 where 
sp_sequence >= 30;
ERROR:  duplicate key value violates unique constraint "skills_pages_sequence"
stainburn=# 



Re: unique key problem on update

От
Thomas Kellerer
Дата:
Gary Stainburn wrote on 20.09.2013 18:07:
> I want to add a new page after page 2 so I try to increase the sequence number
> of each row from page 3 onwards to make space in the sequence for the new
> record. However, I get duplicate key errors when I try. Can anyone suggest
> how I get round this.
>
> Also, the final version will be put onto a WordPress web site which means I
> will have to port it to MYSQL which I don't know, so any solution that will
> work with both systems would be a great help.
>

You need to define the primary key as deferrable:

create table skills_pages
( sp_id        serial not null, sp_sequence  integer not null, sp_title     character varying(80), sp_narative  text,
primarykey (sp_id) deferrable
 
);






Re: unique key problem on update

От
Gary Stainburn
Дата:
On Friday 20 September 2013 17:26:58 Thomas Kellerer wrote:
> You need to define the primary key as deferrable:
>
> create table skills_pages
> (
>   sp_id        serial not null,
>   sp_sequence  integer not null,
>   sp_title     character varying(80),
>   sp_narative  text,
>   primary key (sp_id) deferrable
> );

Cheers. I'll look at that. It's actually the second unique index that's the 
problem but I'm guessing I can set that index up as deferrable too.

Hopefully it'll work for mysql too.

-- 
Gary Stainburn
Group I.T. Manager
Ringways Garages
http://www.ringways.co.uk 



Re: unique key problem on update

От
Thomas Kellerer
Дата:
Gary Stainburn wrote on 20.09.2013 18:30:
>> You need to define the primary key as deferrable:
>>
>> create table skills_pages
>> (
>>    sp_id        serial not null,
>>    sp_sequence  integer not null,
>>    sp_title     character varying(80),
>>    sp_narative  text,
>>    primary key (sp_id) deferrable
>> );
>
> Cheers. I'll look at that. It's actually the second unique index that's the
> problem but I'm guessing I can set that index up as deferrable too.

Ah, sorry didn't see that ;) but, yes it works the same way:

create table skills_pages
(  sp_id        serial not null,  sp_sequence  integer not null,  sp_title     character varying(80),  sp_narative
text, primary key (sp_id),  unique (sp_sequence) deferrable
 
);
 
> Hopefully it'll work for mysql too.
No, it won't.

MySQL neither has deferrable constraints nor does it evaluate them on statement level (they are *always* evaluated
row-by-row).







the value of OLD on an initial row insert

От
James Sharrett
Дата:
I have a number of trigger functions on a table that are performing
various calculations.  The table is a column-wise orientation with
multiple columns that could be updated on a single row.  In one of the
triggers, I'm performing a calculation but don't want the code to run if
the OLD and NEW values are the same value.  This can be resulting from
other triggers that are running on the table.  If there is a truly NEW
(non-NULL) value, I want to run the code.

To deal with this, I'm using the following test in my code where I loop
through the columns that could be updated and test to determine which
column on the row is getting a value assigned.


EXECUTE 'SELECT (' ||quote_literal(NEW) || '::' || TG_RELID::regclass
||').' || quote_ident(metric_record.column_name) INTO changed_metric;       
if not changed_metric is null then

EXECUTE 'SELECT (' ||quote_literal(OLD) || '::' || TG_RELID::regclass
||').' || quote_ident(metric_record.column_name) INTO old_value;

if changed_metric <> old_value then

{calculation code}



This is all doing exactly what I want when the row exists.  However, I
think I'm getting an error if there is a new row getting generated.  I'm
getting the following error when the code runs sometimes:

ERROR: record "old" is not assigned yet
SQL state: 55000
Detail: The tuple structure of a not-yet-assigned record is indeterminate.

Is this what's happening?  If so, how can I avoid the issue.



Thanks,
James





Re: the value of OLD on an initial row insert

От
Luca Ferrari
Дата:
On Fri, Sep 20, 2013 at 6:43 PM, James Sharrett <jsharrett@tidemark.net> wrote:

> ERROR: record "old" is not assigned yet
> SQL state: 55000
> Detail: The tuple structure of a not-yet-assigned record is indeterminate.
>
> Is this what's happening?  If so, how can I avoid the issue.

If I get it right you are running the trigger also for an insert,
which of course does not have an old value. You should either set the
trigger to run only on update statements or enforce your check to see
if the trigger has been invoked for something different than insert
statements.

Luca