2011-01-10 6 views
0

Auf Unique_violation Ausnahme, wie die Zeile aktualisieren oder zu löschen, die die Ausnahmeausführen löschen oder auf eindeutige Verletzung aktualisieren in Postgres

angehoben

Tabellencode und fügen Sie

create table test 
(
id serial not null, 
str character varying NOT NULL, 
is_dup boolean DEFAULT false, 
CONSTRAINT test_str_unq UNIQUE (str) 
); 

INSERT INTO test(str) VALUES ('apple'),('giant'),('company'),('ap*p*le'); 

Funktion

CREATE OR REPLACE FUNCTION rem_chars() 
    RETURNS void AS 
$BODY$ 

BEGIN 
begin 
update test set str=replace(str,'*',''); 
EXCEPTION WHEN unique_violation THEN 
--what to do here to delete the row which raised exception or 
--to update the is_dup=true to that row 
end; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION rem_chars() OWNER TO postgres; 
+0

Was ist es, was Sie tun wollen? LÖSCHEN oder UPDATE in der Ausnahme? –

+0

@hawnn Jeder ist in Ordnung, update oder delete.Ich weiß die Syntax, aber weiß nicht, wie man das auf diese bestimmte Zeile mit where-Klausel anwenden oder Gibt es etwas ähnliches zu last_insert_id, die die ID der Zeile zurückgibt, die Ausnahme ausgelöst. – kiranking

+0

Sie sollten diese Erklärung von Anfang an in der Frage gehabt haben. Ich glaube nicht, dass Sie herausfinden können, welche Zeile das Problem verursacht hat. –

Antwort

0

Ich denke, die einzige Lösung ist, dies in zwei Schritten zu tun:

 
UPDATE test 
    SET str = replace(str,'*','') 
    WHERE str NOT IN (SELECT replace(str,'*','') FROM test); 

UPDATE test 
    SET is_dup = true 
    WHERE str IN (SELECT replace(str,'*','') FROM test); 

Zumindest kann ich nicht auf eine effizientere Weise denken.

1

- das zeigt Ihnen alle möglichen Schlüssel Kollisionen

SELECT a.id, a.str, b.id , b.str 
FROM test a, test b 
WHERE a.str = replace(b.str,'*','') 
AND a.id < b.id; 

- dies wird löschen

DELETE FROM test WHERE id IN (
    SELECT b.id 
    FROM test a, test b 
    WHERE a.str = replace(b.str,'*','') 
    AND a.id < b.id 
);