From: | "Andrus Moor" <nospameetasoftnospam(at)online(dot)ee> |
---|---|
To: | pgsql-sql(at)postgresql(dot)org |
Subject: | Re: Merging item codes using referential integrity |
Date: | 2005-04-03 10:50:05 |
Message-ID: | d2ohp3$pt5$1@news.hub.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-sql |
> Andrus Moor wrote:
>> I have item table and a lot of child tables where the items are used.
>> I want to merge two item codes into single item in all tables.
>> It is not nice to write a lot of separate UPDATE statements for each
>> table.
>> So I want to utilize REFERENCES clause for merging.
>>
>> I tried the following code but got duplicate key error in UPDATE
>> statement.
>>
>> Any idea how to impement this?
>>
>> CREATE TABLE parent ( code CHAR(10) PRIMARY KEY );
>
>> BEGIN;
>> -- Direct Postgres to update all child tables. This causes error.
>> UPDATE parent SET code='1' WHERE code='2';
>> -- Remove duplicate row
>
> That's the problem - you can't have a duplicate row at *any* time with a
> primary key. The UNIQUE constraint is instant and can't be deferred (at
> least, not yet).
>
> However, in this case I would simply write a function:
>
> CREATE FUNCTION merge_all(char(10), char(10) AS '
> UPDATE table_1 SET col_1=$2 WHERE col1=$1;
> UPDATE table_2 SET col_2=$2 WHERE col2=$2;
> ...etc...
> ' LANGUAGE SQL;
>
> Then: SELECT merge_all('OLD_VAL','NEW_VAL') for each value (you could even
> join to your "parent" table if all the values are in there). All the
> updates in the function take place in the same transaction, so if there
> are any problems then all changes will be rolled back.
Richard,
thank you.
Is is possible to determine table_1 , col_1 etc values automatically.
I have some hundreds of referential intgrety constraints which are changing.
So I must write and maintains hundres of additional lines of code which
duplicates existing referential integrity information.
I'm researching the following method:
Input:
Master table name $master and two its primary key values $value1 and
$value2
Output:
1. All $value2 field values in child tables are update to $value1
2. $value2 record is deleted from $master table
Algorithm:
SELECT
childtablename,
childfieldname
FROM pg_referentialinfo
WHERE pg_referentialinfo.mastertable=$master
INTO CURSOR childs;
BEGIN TRANSACTION;
SCAN FOR ALL childs RECORDS;
UPDATE (childs.childtablename) set (childs.childfieldname)=$value2
WHERE EVAL(childs.childfieldname)=$value1;
ENDSCAN;
SELECT
primarykeyfieldname
FROM pg_tables
WHERE pg_tables.tablename=$master
INTO CURSOR mfield;
DELETE FROM $master WHERE EVAL(mfield.primarykeyfieldname)=$value2;
COMMIT;
How to implement SCAN FOR ALL childs RECORDS in PostgreSQL ?
Andrus.
From | Date | Subject | |
---|---|---|---|
Next Message | Sean Davis | 2005-04-03 12:38:41 | Re: a very big table |
Previous Message | Axel Straschil | 2005-04-03 10:13:48 | How to store directory like structures? |