Đặt giá trị mặc định của cột thành nối hai giá trị của cột khác?


13

Tôi có một cơ sở dữ liệu Postgresql 8.1. Trong một bảng, có ba cột: first_name, last_name, display_name.

Có thể đặt giá trị mặc định display_namefirst_name + " " + last_name?


Tôi biết đây là một bài viết hơn 7 năm tuổi. Nhưng, chỉ để tò mò, bạn không nên sử dụng view cho trường hợp này? Không cần cập nhật, không cần cửa hàng, không cần kích hoạt vv?
Khắc nghiệt

Câu trả lời:


15

Sử dụng một kích hoạt.

Đây là một số mã bạn có thể sử dụng làm cơ sở. Nếu bạn cũng cần xử lý CẬP NHẬT, chỉ cần một thay đổi nhỏ.

 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=#

Cảm ơn! Không phải dòng sẽ CREATE TRIGGER people_insert BEFORE INSERT OR UPDATE...xử lý cập nhật là tốt?
MattSayar

Ồ, vâng.
Phải

display_name có lẽ nên là 41, nếu bạn quan tâm. Vì bạn thêm một khoảng trắng giữa hai cột 20 char.
isaaclw

Tôi thấy rằng giải pháp này tăng thêm khoảng 15% chi phí cho hoạt động chèn :-(
Akvel

17

Bạn không cần phải thực sự lưu trữ giá trị; bạn có thể tạo một hàm có thể được tham chiếu giống như một cột được tạo. Một lưu ý là các tài liệu tham khảo phải luôn đủ điều kiện với tên bảng hoặc bí danh.

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;

Kết quả:

id | tên hiển thị
---- + --------------
  1 | John Smith
  2 | Jane Doe
  3 | Hoàng tử
(3 hàng)

Bạn thậm chí có thể lập chỉ mục cho giá trị được tạo, bao gồm sử dụng các tìm kiếm KNN dựa trên độ tương tự của bát quái. Ví dụ:

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;

Loại tìm kiếm này trả về các hàng từ quét chỉ mục theo thứ tự "khoảng cách" từ chuỗi tìm kiếm. Nếu bạn muốn xem mức độ "đóng" của chúng, bạn có thể sử dụng toán tử khoảng cách ( <->) hoặc similarity()hàm (là 1 - distance). Một tìm kiếm KNN có thể trả về K "hàng xóm gần nhất" rất nhanh, ngay cả với một tập dữ liệu rất lớn.


Tôi thực sự cần phải lưu trữ giá trị cho khả năng tương thích ngược, nhưng đây là một cách tiếp cận khá tuyệt vời! Phần OCD trong tôi cũng muốn có một kiểm tra cho họ của NULL, nhưng điều đó có thể có nghĩa là bạn có vấn đề về tính toàn vẹn dữ liệu lớn hơn để lo lắng vào thời điểm đó
MattSayar

Vâng, tôi tuyên bố last_nameNOT NULL trong ví dụ của tôi. :-- Nếu bạn có mã không nhất quán về các tham chiếu cột đủ điều kiện, tôi có thể thấy nơi đó có thể là một nỗi đau để theo dõi tất cả các trường hợp đó.
kgrittn

2

Với cài đặt DEFAULT trên bảng cột, không.

Đặt cược tốt nhất của bạn ở đây là TRIGGER với giá trị MỚI cho mỗi cột bạn muốn tính toán.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.