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

CHỌN hoặc THỰC HIỆN trong một hàm PL / pgSQL

Trong mã plpgsql, SELECT mà không có mục tiêu sẽ gây ra lỗi. Nhưng rõ ràng bạn không không muốn SELECT INTO , bạn chỉ muốn đặt trạng thái của FOUND . Bạn sẽ sử dụng PERFORM cho điều đó.

  • SELECT tăng ngoại lệ trong hàm PL / pgSQL

Tốt hơn, nhưng , sử dụng IF EXISTS ... . Hãy xem xét việc viết lại hàm này của bạn:

CREATE OR REPLACE FUNCTION "insertarNuevoArticulo"( nombrearticulo text, descripcion text, idtipo int, idfamilia bigint, artstock int, minstock int, maxstock int, idmarca bigint, precio real, marcastock int)
  RETURNS boolean
  LANGUAGE plpgsql AS
$func$
DECLARE
    _id_articulo "Articulo"."idArticulo"%TYPE;
BEGIN
    SELECT a."idArticulo" INTO _id_articulo
    FROM   "Articulo" a
    WHERE  a."Nombre" = $1 AND a."idTipo" = $3 AND a."idFamilia" = $4;

    IF NOT FOUND THEN
        INSERT INTO "Articulo"("Nombre", "Descripcion", "idTipo", "idFamilia", "Stock", "MinStock", "MaxStock")
        VALUES ($1, $2, $3, $4, $5, $6, $7)
        RETURNING "Articulo"."idArticulo" INTO _id_articulo;
    END IF;

   IF EXISTS (SELECT FROM "ArticuloMarca" a
              WHERE a."idArticulo" = _id_articulo AND a."idMarca" = $8) THEN
      RETURN false;
   ELSE
      INSERT INTO "ArticuloMarca"("idArticulo", "idMarca", "PrecioReferencial", "Stock")
      VALUES (_id_articulo, $8, $9, $10);
      RETURN true;
    END IF;
END
$func$;

Giới thiệu về EXISTS :

  • Kiểm tra PL / pgSQL nếu một hàng tồn tại

Điểm chính khác :

  • Sử dụng RETURNING mệnh đề của INSERT thay vì một SELECT bổ sung .

Postgres 9.5+

Trong Postgres 9.5 trở lên, hãy sử dụng INSERT ... ON CONFLICT DO NOTHING (a.k.a. "UPSERT") để thay thế.
Bạn sẽ có UNIQUE ràng buộc về "Articulo"("Nombre", "idTipo", "idFamilia")"ArticuloMarca"("idArticulo", "idMarca") và sau đó:

CREATE OR REPLACE FUNCTION insert_new_articulo( nombrearticulo text, descripcion text, idtipo int, idfamilia bigint, artstock int, minstock int, maxstock int, idmarca bigint, precio real, marcastock int)
  RETURNS boolean
  LANGUAGE plpgsql AS
$func$
DECLARE
    _id_articulo "Articulo"."idArticulo"%TYPE;
BEGIN
   LOOP
      SELECT "idArticulo" INTO _id_articulo
      FROM   "Articulo"
      WHERE  "Nombre" = $1 AND "idTipo" = $3 AND "idFamilia" = $4;

      EXIT WHEN FOUND;

      INSERT INTO "Articulo"("Nombre", "Descripcion", "idTipo", "idFamilia", "Stock", "MinStock", "MaxStock")
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON     CONFLICT (tag) DO NOTHING
      RETURNING "idArticulo" INTO _id_articulo;

      EXIT WHEN FOUND;
   END LOOP;

   LOOP
      INSERT INTO "ArticuloMarca"("idArticulo", "idMarca", "PrecioReferencial", "Stock")
      VALUES (_id_articulo, $8, $9, $10)
      ON     CONFLICT ("idArticulo", "idMarca") DO NOTHING;

      IF FOUND THEN
         RETURN true;
      END IF;

      IF EXISTS (SELECT FROM "ArticuloMarca"
                 WHERE "idArticulo" = _id_articulo AND "idMarca" = $8) THEN
         RETURN false;
      END IF;
   END LOOP;
END
$func$;

Điều này nhanh hơn, đơn giản hơn và đáng tin cậy hơn. Các vòng lặp được thêm vào loại trừ mọi điều kiện đua còn lại với việc ghi đồng thời (trong khi hầu như không thêm bất kỳ chi phí nào). Không cần ghi đồng thời, bạn có thể đơn giản hóa. Giải thích chi tiết:

  • 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?
  • Cách sử dụng RETURNING với ON CONFLICT trong PostgreSQL?

Ngoài ra:sử dụng các số nhận dạng hợp pháp, viết thường để tránh tất cả các dấu ngoặc kép ồn ào.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chọn nhiều giá trị max () bằng cách sử dụng một câu lệnh SQL

  2. Cách ghi khung dữ liệu Pandas vào mô hình Django

  3. Xuất các hàng cụ thể từ bảng PostgreSQL dưới dạng INSERT SQL script

  4. pgDash Diagnostics Alternatives - PostgreSQL Query Management with ClusterControl

  5. PostgreSQL Full Text Search và Trigram Confusion