PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tên cột PL / pgSQL giống như biến

Giả sử id_pracownikaPRIMARY KEY của cái bàn. Hoặc ít nhất được xác định UNIQUE . (Nếu nó không phải là NOT NULL , NULL là một trường hợp góc.)

SELECT hoặc INSERT

Chức năng của bạn là một cách triển khai khác của "SELECT hoặc INSERT" - một biến thể của UPSERT vấn đề phức tạp hơn khi đối mặt với tải ghi đồng thời hơn có thể tưởng tượng. Xem:

  • CHỌN hoặc CHÈN trong một hàm có nguy cơ gặp phải các điều kiện về chủng tộc không?

Với UPSERT trong Postgres 9.5 trở lên

Trong Postgres 9.5 trở lên, hãy sử dụng UPSERT (INSERT ... ON CONFLICT ... ) Chi tiết trong Postgres Wiki. Cú pháp mới này thực hiện một công việc rõ ràng :

CREATE OR REPLACE FUNCTION hire(
        _id_pracownika integer
      , _imie varchar
      , _nazwisko varchar
      , _miasto varchar
      , _pensja real)
  RETURNS text
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO pracownicy
          ( id_pracownika, imie, nazwisko, miasto, pensja)
   VALUES (_id_pracownika,_imie,_nazwisko,_miasto,_pensja);
   ON     CONFLICT DO NOTHING
   RETURNING 'OK';

   IF NOT FOUND THEN
      RETURN 'JUZ ISTNIEJE';
   END IF;
END
$func$;

Các tên cột đủ điều kiện trong bảng để phân biệt khi cần thiết. (Bạn cũng có thể đặt tiền tố cho các tham số hàm với tên hàm, nhưng điều đó thật khó hiểu, dễ dàng.)
Nhưng tên cột trong danh sách đích của một INSERT có thể không đủ tiêu chuẩn trong bảng. (Dù sao cũng không bao giờ mơ hồ.)

Tốt nhất hãy tránh những điều mơ hồ như vậy trước, như vậy sẽ ít mắc lỗi hơn. Một số (bao gồm cả tôi) thích làm điều đó bằng cách thêm dấu gạch dưới vào trước tất cả các tham số và biến hàm.

Nếu bạn tích cực cần tên cột cũng như tên tham số hàm, một cách để tránh xung đột đặt tên là sử dụng ALIAS bên trong hàm. Một trong những trường hợp hiếm hoi mà ALIAS thực sự hữu ích.

Hoặc tham chiếu các tham số hàm theo vị trí thứ tự: $1 cho id_pracownika trong trường hợp này.

Nếu vẫn không thành công, bạn có thể quyết định điều gì được ưu tiên bằng cách đặt #variable_conflict . Xem:

  • Xung đột đặt tên giữa tham số hàm và kết quả của mệnh đề JOIN với USING

Còn nữa:

  • Có những điều phức tạp đối với RETURNING trong một UPSERT. Xem:

    • Cách sử dụng RETURNING với ON CONFLICT trong PostgreSQL?
  • Các ký tự chuỗi (hằng số văn bản) phải được đặt trong dấu ngoặc kép:'OK', không phải "OK" . Xem:

    • Chèn văn bản với các dấu ngoặc kép trong PostgreSQL
  • Việc gán các biến tương đối đắt hơn so với các ngôn ngữ lập trình khác. Giữ bài tập ở mức tối thiểu để có hiệu suất tốt nhất trong plpgsql. Thực hiện trực tiếp càng nhiều càng tốt trong các câu lệnh SQL.

  • VOLATILE COST 100 là trình trang trí mặc định cho các chức năng. Không cần phải đánh vần chúng.

Không có UPSERT trong Postgres 9.4 trở lên

...
   IF EXISTS (SELECT FROM pracownicy p
             WHERE  p.id_pracownika = hire.id_pracownika) THEN
      RETURN 'JUZ ISTNIEJE';
   ELSE
      INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja)
      VALUES (hire.id_pracownika,hire.imie,hire.nazwisko,hire.miasto,hire.pensja);
    
      RETURN 'OK';
   END IF;
...

Trong một EXISTS biểu thức, SELECT danh sách không quan trọng. SELECT id_pracownika , SELECT 1 hoặc thậm chí SELECT 1/0 - tất cả đều giống nhau. Chỉ cần sử dụng SELECT trống danh sách. Chỉ sự tồn tại của bất kỳ hàng đủ điều kiện nào mới là vấn đề. Xem:

  • Điều gì dễ đọc hơn trong các truy vấn phụ EXISTS?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LỖI:quyền bị từ chối đối với tên bảng quan hệ trên Postgres trong khi thử SELECT với tư cách người dùng chỉ đọc

  2. Mẹo điều chỉnh hiệu suất PostgreSQL

  3. Mảng ban đầu trong chức năng tổng hợp mảng đa chiều

  4. Tổng quan về Tham số kết nối sslpassword của PostgreSQL 13 libpq

  5. Có gì mới trong Postgres-XL 9.6