PostgreSQL: от OID до Bytea - PullRequest
       10

PostgreSQL: от OID до Bytea

4 голосов
/ 18 февраля 2011

Мы решили перейти от OID s в нашей базе данных PostgreSQL 9.0 и использовать вместо нее bytea столбцы. Я пытаюсь скопировать данные из одного столбца в другой, но не могу найти правильный запрос. Это самое близкое, что я получил:

update user as thistable set pkcs_as_bytea = (select array_agg(mylargeobject.data) from 
  (select * from pg_largeobject where loid = thistable.pkcs12_as_oid order by pageno) as mylargeobject) where thistable.pkcs12 is not null

И это дает мне следующее сообщение об ошибке:

ERROR:  column "pkcs_as_bytea" is of type bytea but expression is of type bytea[]

Какой тогда будет правильный запрос?

Ответы [ 4 ]

4 голосов
/ 28 апреля 2012

Другим способом, который не требует пользовательских функций, является использование комбинации loread(lo_open(...)), например:

UPDATE user SET pkcs_as_bytea = loread(lo_open(pkcs12_as_oid, 262144), 1000000) WHERE thistable.pkcs12 IS NOT NULL

Существует проблема с этим кодом, функция loread требует в качестве второго параметра максимальное количество байтов для чтения (параметр 1000000, который я использовал выше), поэтому вам следует использовать действительно большое число, если данные большие. В противном случае содержимое будет обрезано после такого количества байтов, и вы не вернете все данные обратно в поле bytea.

Если вы хотите преобразовать OID в текстовое поле, вам также следует использовать функцию преобразования, например:

UPDATE user SET pkcs_as_text = convert_from(loread(lo_open(pkcs12_as_oid, 262144), 1000000), 'UTF8')

(262144 - флаг для открытого режима, 40000 в гекса, что означает «открытый только для чтения»)

1 голос
/ 21 февраля 2011

Вот хранимая процедура, которая делает волшебство:

CREATE OR REPLACE FUNCTION merge_oid(val oid) 
returns bytea as $$
declare merged bytea;
declare arr bytea;
 BEGIN  
   FOR arr IN SELECT data from pg_largeobject WHERE loid = val ORDER BY pageno LOOP
     IF merged IS NULL THEN
       merged := arr;
     ELSE
       merged := merged || arr;
     END IF;
   END LOOP;
  RETURN merged;

END  
$$ LANGUAGE plpgsql;
0 голосов
/ 27 февраля 2019

ну, я сделал что-то подобное.У меня есть таблица вложений и столбец содержимого с данными в типе oid.Я перенес четыре действия:

ALTER TABLE attachment add column content_bytea bytea
UPDATE attachment SET content_bytea = lo_get(content)
ALTER TABLE attachment drop column content
ALTER TABLE attachment rename column content_bytea to content
0 голосов
/ 18 февраля 2011

Вам нужно что-то вроде array_to_string(anyarray, text) для текстовых массивов, но в этом случае array_to_bytea(largeobjectarray) для объединения всех разделов.Вы должны создать эту функцию самостоятельно или обработать ее в логике приложения.

...