sql >> Databáze >  >> RDS >> PostgreSQL

Porozumění obsazení z bytea na oid

Herecké obsazení není skutečné obsazení. Je to jen (ab)používá pohodlnou syntaxi. velký objekt (LO) se vytvoří na pozadí, které je uloženo samostatně, a vrátí se OID, které na něj odkazuje.

Podle dokumentace:

Vrácené OID je v podstatě FK k PK systémové tabulky pg_largeobject .

CREATE TABLE je zcela nezávislý na funkci a pseudoobsazení.

CREATE TABLE bytea_to_lo (
   largeObj lo 
);

Je to jen typický případ použití výše vytvořeného obsazení úkolu, což je zřejmé z následujícího řádku, který jste zapomněli citovat:

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

Co se zde stane?

Datový typ lo je doména nad základním typem oid , vytvořený doplňkovým modulem lo (nesprávně uváděno jako „balíček lo_manage“ v blog enty Grace Batumbya ). Podle dokumentace:

Funkce decode() vrátí bytea . INSERT příkaz přiřadí bytea hodnotu do sloupce largeObj , což spustí přetypování přiřazení na jeho typ lo , a to je místo, kde přichází na řadu výše uvedené obsazení.

Varování / Oprava / Aktualizace

Záznam blogu je nedbalý a zastaralý.

  • Neobtěžuje se to zmínit (podle dokumentace ):

    Ve skutečnosti musíte být superuživatel.

  • Překlep v CREATE TABLE :název a typ sloupce obrácený.

  • Definice funkce je podrobná a neefektivní. To by bylo lepší (pro Postgres 9.3 nebo starší):

    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.

K dispozici je vestavěný funkce k tomu v Postgres 9.4 . Místo toho použijte toto:

lo_from_bytea(loid oid, string bytea)

Z poznámek k vydání :

Pro CREATE CAST (podle dokumentace ):

Navrhuji přetíženou variantu pouze s bytea parametr:

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;

Vzhledem k tomu, že pseudoobsazení má docela velký vedlejší efekt, nejsem přesvědčen, že to mám udělat ASSIGNMENT obsazení. Pravděpodobně bych začal s explicitně pouze:




  1. Jak vytvořit kaskádové rozevírací seznamy pomocí mysql a php

  2. to_sql pyodbc count pole nesprávné nebo chyba syntaxe

  3. Každopádně omezit dobu provádění dotazu MySQL?

  4. Atomová víceřadá aktualizace s jedinečným omezením