Ich habe eine Postgresql 8.1-Datenbank. In einer Tabelle gibt es drei Spalten: first_name, last_name, display_name.
Ist es möglich, den Standardwert von display_namezu setzen first_name + " " + last_name?
Ich habe eine Postgresql 8.1-Datenbank. In einer Tabelle gibt es drei Spalten: first_name, last_name, display_name.
Ist es möglich, den Standardwert von display_namezu setzen first_name + " " + last_name?
Antworten:
Verwenden Sie einen Abzug.
Hier ist ein Code, den Sie als Basis verwenden können. Wenn Sie auch UPDATEs verarbeiten müssen, ist nur eine kleine Änderung erforderlich.
create table people
(
first_name varchar(20),
last_name varchar(20),
display_name varchar(40)
);
CREATE TABLE
CREATE OR REPLACE FUNCTION people_insert() RETURNS trigger AS '
BEGIN
NEW.display_name := NEW.first_name||'' ''||NEW.last_name;
RETURN NEW;
END;
' LANGUAGE plpgsql;
postgres=# CREATE FUNCTION
CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE ON people FOR
EACH ROW EXECUTE PROCEDURE people_insert();
postgres=# CREATE TRIGGER
insert into people values ('Larry','Ellison');
postgres=# INSERT 0 1
postgres=# select * from people;
first_name | last_name | display_name
------------+-----------+---------------
Larry | Ellison | Larry Ellison
(1 row)
postgres=#
CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE...die Aktualisierung zuständig?
Sie müssen den Wert nicht wirklich speichern . Sie können eine Funktion erstellen, auf die ähnlich wie auf eine generierte Spalte verwiesen werden kann. Die einzige Einschränkung ist, dass Referenzen immer mit dem Tabellen- oder Aliasnamen qualifiziert werden müssen.
CREATE TABLE person
(
id int PRIMARY KEY,
first_name text,
last_name text NOT NULL
);
INSERT INTO person
VALUES
(1, 'John', 'Smith'),
(2, 'Jane', 'Doe'),
(3, NULL, 'Prince');
CREATE FUNCTION display_name(rec person)
RETURNS text
STABLE
LANGUAGE SQL
COST 5
AS $$
SELECT
CASE
WHEN $1.first_name IS NULL THEN ''
ELSE $1.first_name || ' '
END || $1.last_name;
$$;
SELECT p.id, p.display_name FROM person p;
Die Ergebnisse:
id | Anzeigename ---- + -------------- 1 | John Smith 2 | Jane Doe 3 | Prinz (3 Reihen)
Sie können den generierten Wert sogar indizieren, einschließlich der Verwendung von KNN-Suchen basierend auf der Trigrammähnlichkeit. Beispielsweise:
CREATE EXTENSION pg_trgm;
CREATE INDEX person_trgm_name
ON person
USING gist
(display_name(person) gist_trgm_ops);
SELECT
p.id,
p.display_name,
similarity(p.display_name, 'Jane')
FROM person p
ORDER BY p.display_name <-> 'Jane'
LIMIT 2;
Diese Art der Suche gibt Zeilen aus dem Index-Scan in der Reihenfolge der "Entfernung" von der Suchzeichenfolge zurück. Wenn Sie sehen möchten, wie "nah" sie waren, können Sie entweder den Entfernungsoperator ( <->) oder die similarity()Funktion (dh 1 - Entfernung) verwenden. Eine KNN-Suche kann sehr schnell die K "nächsten Nachbarn" zurückgeben, selbst bei einem sehr großen Datensatz.
last_name, NOT NULLin meinem Beispiel zu sein. :-) Wir hatten Namensspalten wie die, die in der Tabelle waren und von Triggern gepflegt und ohne großen Aufwand auf diesen Ansatz umgestellt wurden, aber unser Framework verwendet immer einen Alias und qualifiziert immer Referenzen, sodass dieser Teil einfach war. Wenn Sie Code haben, der hinsichtlich der Qualifizierung von Spaltenreferenzen nicht konsistent ist, kann ich sehen, wo es ein Problem sein kann, all diese Fälle aufzuspüren.