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

Hiểu dàn diễn viên từ bytea đến oid

Dàn diễn viên không phải là dàn diễn viên thực thụ. Nó chỉ là (ab) bằng cách sử dụng cú pháp thuận tiện. vật thể lớn (LO) được tạo trong nền được lưu trữ riêng biệt và OID tham chiếu đến nó được trả về.

Theo tài liệu:

OID trả về về cơ bản là FK cho PK của bảng hệ thống pg_largeobject .

CREATE TABLE hoàn toàn độc lập với hàm và giả đúc.

CREATE TABLE bytea_to_lo (
   largeObj lo 
);

Đó chỉ là một trường hợp sử dụng điển hình cho phép gán ghép được tạo ở trên, điều này trở nên rõ ràng từ dòng sau mà bạn quên trích dẫn:

INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));

Điều gì xảy ra ở đây?

Kiểu dữ liệu lo là một miền trên loại cơ sở oid , được tạo bởi mô-đun bổ sung lo (được tham chiếu không chính xác là "gói lo_manage" trong blog của Grace Batumbya ). Theo tài liệu:

Hàm decode() trả về bytea . INSERT câu lệnh gán bytea giá trị cho cột largeObj , kích hoạt một phép gán cho kiểu của nó lo và đó là nơi xuất hiện của dàn diễn viên ở trên.

Cảnh báo / Khắc phục / Cập nhật

Mục nhập blog bây giờ là cẩu thả và lỗi thời.

  • Không bận tâm đến điều đó ( theo tài liệu ):

    Một cách hiệu quả, bạn phải là siêu người dùng.

  • Đánh máy trong CREATE TABLE :tên và kiểu cột bị đảo ngược.

  • Định nghĩa chức năng dài dòng và không hiệu quả. Điều này sẽ tốt hơn (đối với Postgres 9.3 trở lên):

    CREATE OR REPLACE FUNCTION blob_write(bytea)
      RETURNS oid AS
    $func$
    DECLARE
       loid oid := lo_create(0);
       lfd  int := lo_open(loid,131072);  -- = 2^17 = x2000
       -- symbolic constant defined in the header file libpq/libpq-fs.h
       -- #define   INV_WRITE   0x00020000
    BEGIN
       PERFORM lowrite(lfd, $1);
       PERFORM lo_close(lfd);
       RETURN loid;
    END
    $func$  LANGUAGE plpgsql VOLATILE STRICT;
    

    SQL Fiddle.

Có một được tích hợp sẵn chức năng cho điều này trong Postgres 9.4 . Sử dụng cái đó thay thế:

lo_from_bytea(loid oid, string bytea)

Từ ghi chú phát hành :

Đối với CREATE CAST ( theo tài liệu ):

Tôi đề xuất một biến thể quá tải chỉ có bytea tham số:

CREATE OR REPLACE FUNCTION lo_from_bytea(bytea)
   RETURNS oid LANGUAGE sql AS
'SELECT lo_from_bytea(0, $1)';

CREATE CAST (bytea AS oid) WITH FUNCTION lo_from_bytea(bytea) AS ASSIGNMENT;

Vì diễn viên giả có tác dụng phụ khá lớn, tôi không bị thuyết phục để thực hiện ASSIGNMENT dàn diễn viên. Tôi có thể bắt đầu với chỉ rõ ràng:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL DATEADD () Tương đương

  2. Cách thay đổi mã hóa bộ sưu tập cơ sở dữ liệu mẫu

  3. SQL giải thích kế hoạch:Materialize là gì?

  4. Flask-Migrate không phát hiện bảng

  5. nhầm lẫn cổng postgresql 5433 hay 5432?