Loop over bytea

0

Witajcie,

Mam nietypowy problem. W jednej z tabel jest kolumna typu bytea. To co znajduje się w kolumnie to "zestawy" dwóch informacji (integer) zapisanych na dwóch bajtach każdy. Przykład:
punkty o numerach 2,3,4 (dec) o wartości: 100 (0078 hex) oraz punkty 6,7 (dec) o wartości 1220 (040C hex) każdy z nich w tej kolumnie bytea są zapisane jak poniżej (hex) - znak "|" dałem dla zobrazowania o co mi chodzi:

0002|0078|0003|0078|0004|0078|0006|04C4|0007|04C4

Dzięki interfejsowi w Delphi (firedac i TBlobField) i możliwościom

type
  TSQLBytea = packed record
     point: word;
     value: word;
  end;

w zasadzie tylko byte rzytuję na TSQLBytea i mam to co potrzebuję.

Niestety zmieniła się nieco koncepcja i to co teraz robię w delphi czyli rzutowanie byte na konkretny typ aby dowiedzieć się, który punkt i jaką wartość ten puknt ma muszę zrobić po stronie funkcji w postgresie.

No i zrobiłem mniej więcej tak jak tutaj:
https://stackoverflow.com/questions/9987215/bytea-in-postgres-storing-and-retrieving-bytes

jednak mnie to nie satysfakcjonuje, a że nie mam doświadczenia w typach w postgresql to pytanie do was forumowicze, czy udałoby się zrobić taki packed record (TSQLBytea ) w postgresie i rzutować po 4 byte na ten konkretny typ?

Może macie jakiś pomysł jak to ogarnąć inaczej? Docelowo muszę ten cały bytea podzielić na N punktów (4 byte na punkt) i zrobić insert do innej tabeli (point, value).

0

A dlaczego chcesz to trzymać w polu typu byte?

0

Powiedzmy, że tak zostało to wymyślone dla wcześniejszej wersji systemu i się to sprawdzało. Teraz koncepcja się zmieniła i trzeba by przerobić kilka innych elementów systemu, które na tym polu operują aby się tego bytea pozbyć. Także łatwiej i szybciej będzie jak ja to zrobię "pod spodem" po stronie postgersa

4

@woolfik: można kombinować w takim kierunku jak niżej: https://dbfiddle.uk/?rdbms=postgres_12&fiddle=ee320398cf6f0c61434d11948e7f07a0
(Nie sprawdzałem czy funkcje dostępne są na wersjach < 12)

create table foo (id int, bytes bytea);

insert into foo values (1,decode('000200780003007800040078','hex'));
insert into foo values (2,decode('000604C4000704C4','hex'));

select 
     length(f.bytes) len_bytes,
     generate_series(0,length(f.bytes)-4,4) as b_start,
     f.*
  from foo f
;


with helper as (
  select 
     generate_series(0,length(f.bytes)-4,4) as b_start,
     encode(bytes,'hex')::text as_string,
     f.*
  from foo f
)
select
  to_hex(get_byte(bytes,b_start))   byte_1,
  to_hex(get_byte(bytes,b_start+1)) byte_2,
  to_hex(get_byte(bytes,b_start+2)) byte_3,
  to_hex(get_byte(bytes,b_start+3)) byte_4,
  h.* 
from helper h
order by id,b_start
;

1 użytkowników online, w tym zalogowanych: 0, gości: 1