sql >> Database teknologi >  >> RDS >> PostgreSQL

Forståelse af cast fra bytea til oid

Rollebesætningen er ikke en ægte rollebesætning. Det er bare at (misbruge) den praktiske syntaks. Et stort objekt (LO) oprettes i baggrunden, som gemmes separat, og den OID, der refererer til den, returneres.

Pr. dokumentation:

Det returnerede OID er dybest set en FK til PK i systemtabellen pg_largeobject .

OPRET TABEL er fuldstændig uafhængig af funktionen og pseudo-castet.

CREATE TABLE bytea_to_lo (
   largeObj lo 
);

Det er bare en typisk use case for opgavebesætningen oprettet ovenfor, hvilket fremgår af følgende linje, som du glemte at citere:

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

Hvad sker der her?

Datatypen lo er et domæne over basistypen oid , oprettet af det ekstra modul lo (forkert omtalt som "lo_manage-pakke" i Blogenty af Grace Batumbya ). Pr. dokumentation:

Funktionen decode() returnerer bytea . INSERT sætningen tildeler bytea værdi til kolonnen largeObj , som udløser en opgave cast til dens type lo , og det er her, ovenstående rollebesætning kommer ind.

Advarsel / Korrigerende / Opdatering

Blogindlægget er sjusket og forældet efterhånden.

  • Gider ikke nævne det (pr. dokumentation ):

    Faktisk skal du være superbruger.

  • Skrivefejl i CREATE TABLE :kolonnenavn og type omvendt.

  • Funktionsdefinitionen er omfattende og ineffektiv. Dette ville være bedre (for Postgres 9.3 eller ældre):

    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.

Der er en indbygget funktion for dette i Postgres 9.4 . Brug det i stedet:

lo_from_bytea(loid oid, string bytea)

Fra udgivelsesbemærkningerne :

For CREATE CAST (pr. dokumentation ):

Jeg foreslår en overbelastet variant med kun en bytea parameter:

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;

Da pseudo-castet har en ret stor bivirkning, er jeg ikke overbevist om at gøre det til en OPDRAGELSE støbt. Jeg ville nok starte med kun eksplicit:




  1. forsøger at eksportere java-kildekode fra en Oracle-database

  2. SQL rækker i kolonner

  3. Prisma, hvordan man vender om rækkefølge

  4. mysql erstatte til alternativ