Ho un database Postgresql 8.1. In una tabella, ci sono tre colonne: first_name
, last_name
, display_name
.
È possibile impostare il valore predefinito di display_name
essere first_name + " " + last_name
?
Ho un database Postgresql 8.1. In una tabella, ci sono tre colonne: first_name
, last_name
, display_name
.
È possibile impostare il valore predefinito di display_name
essere first_name + " " + last_name
?
Risposte:
Usa un grilletto.
Ecco un po 'di codice che puoi usare come base. Se è necessario gestire anche gli AGGIORNAMENTI, è necessaria solo una piccola modifica.
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...
gestirà anche l'aggiornamento?
Non è necessario archiviare effettivamente il valore; puoi creare una funzione a cui puoi fare riferimento in modo molto simile a una colonna generata. L'unica avvertenza è che i riferimenti devono sempre essere qualificati con il nome della tabella o alias.
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;
I risultati:
id | nome da visualizzare ---- + -------------- 1 | John Smith 2 | Jane Doe 3 | Principe (3 file)
Puoi persino indicizzare il valore generato, incluso l'uso delle ricerche KNN basate sulla somiglianza del trigramma. Per esempio:
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;
Questo tipo di ricerca restituisce le righe dalla scansione dell'indice in ordine di "distanza" dalla stringa di ricerca. Se vuoi vedere quanto fossero "vicini", puoi usare l'operatore di distanza ( <->
) o la similarity()
funzione (che è 1 - distanza). Una ricerca KNN può restituire K "vicini più vicini" molto rapidamente, anche con un set di dati molto grande.
last_name
di essere NOT NULL
nel mio esempio. :-) Avevamo nomi di colonne come quelli che erano nella tabella e mantenuti dai trigger e passati a questo approccio senza troppi problemi, ma il nostro framework utilizza sempre un alias e qualifica sempre i riferimenti, quindi quella parte è stata facile. Se hai un codice che non è coerente con i riferimenti alle colonne qualificanti, posso vedere dove potrebbe essere difficile rintracciare tutti quei casi.