PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Разбиране на прехвърлянето от bytea към oid

Актьорският състав не е истински актьорски състав. Това е просто (зло)използване на удобния синтаксис. голям обект (LO) се създава във фонов режим, който се съхранява отделно и OID, който го препраща, се връща.

Съгласно документацията:

Върнатият OID е основно FK към PK на системната таблица pg_largeobject .

СЪЗДАВАНЕ НА ТАБЛИЦА е напълно независим от функцията и псевдокаста.

CREATE TABLE bytea_to_lo (
   largeObj lo 
);

Това е просто типичен случай на употреба за създаденото по-горе присвояване, което става очевидно от следния ред, който сте забравили да цитирате:

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

Какво се случва тук?

Типът данни lo е домейн над основния тип oid , създаден от допълнителния модул lo (неправилно споменат като „lo_manage package“ в блог обект на Грейс Батумбя ). Съгласно документацията:

Функцията decode() връща bytea . INSERT изразът присвоява bytea стойност в колоната largeObj , което задейства присвояване, преобразувано към неговия тип lo , и тук се намесва горният актьорски състав.

Предупреждение / Корекция / Актуализация

Записът в блога вече е небрежен и остарял.

  • Не си прави труда да споменава това (по документация ):

    Ефективно трябва да сте суперпотребител.

  • Печатна грешка в CREATE TABLE :име на колона и тип обърнати.

  • Дефиницията на функцията е многословна и неефективна. Това би било по-добре (за Postgres 9.3 или по-стари):

    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.

Има вграден функцията за това в Postgres 9.4 . Използвайте това вместо това:

lo_from_bytea(loid oid, string bytea)

От бележки по изданието :

За CREATE CAST (по документация ):

Предлагам претоварен вариант само с bytea параметър:

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;

Тъй като псевдокастът има доста голям страничен ефект, не съм убеден да направя това ЗАДАЧА гласове. Вероятно бих започнал само с изрично:




  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, потребителите на Postgresql и потребителите на Linux са свързани помежду си?

  2. Проверете дали таблицата на sqlachemy е празна

  3. Еволюция на отказоустойчивостта в PostgreSQL:Синхронно записване

  4. Няма достъп до методите на екземпляр на Sequelize

  5. Нормализация на Unicode в Postgres