Kann man char(60) in Array, z.B. char(60)[] nachträglich ändern ?!

Hallo,

ich habe eine große DB von Informix nach PostgreSQL portiert und stelle nun fest, das einige SQL-Abfragen gezielte Positionen in Feldern die als CHAR(60) definiert sind abfragen.
Wie mach ich nun aus einer bestehenden CHAR-Spalte eine CHAR-ARRAY-Spalte ?!

Das Problem:

Nehmen wir an das Feld NAME ist vom Typ CHAR(20)

Unter Informix kann ich mit dem SQL-Statement " WHERE NAME[2]=‘b’ " testen, ob der zweite Buchstabe ein b ist.

Unter Postgres hätte das Feld schon beim Erstellen der Tabelle als ARRAY-Typ CHAR(20)[] definieren müssen.

Wäre toll, wenn ich nicht die ganze DB neu einlesen müßte :frowning:

Vielen Dank im vorraus,

Andreas

klingt nach einer Aufgabe für substring(). Ansonsten gibt es noch string_to_array (text, text). Ansonsten eine SP schreiben, die das tut. Sollte trivial sein.

Andreas

Du könntest auch eine neue Spalte zur Tabelle addieren, mit Hilfe der von akretschmer genannten Funktion(en) die Daten dorthin schreiben, danach die originale Spalte löschen und die neue umbenennen.

Zwischendurch kannst du ja immer wieder mal kontrollieren, ob die Ergebnisse deinen Erwartungen entsprechen.

Just for fun:

create or replace function text2array(text) returns char[] as $$
declare
        i       int;
        a       char[];

begin
        i := length($1);
        for i in 1 .. length($1) loop
                a[i] := substring($1, i, 1);
        end loop;
        return a;
end;
$$ language plpgsql immutable;

Und der Einsatz:

test=# create table foo (id serial, wert text);
NOTICE:  CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"
CREATE TABLE
test=*# insert into foo (wert) values ('blafasel');
INSERT 0 1
test=*# insert into foo (wert) values ('blubber labber');
INSERT 0 1
test=*# select id, (text2array(wert))[4] from foo;
 id | text2array
----+------------
  1 | f
  2 | b
(2 rows)

Das zu verwenden, um wie ads vorschlug, eine neue Spalte zu erzeugen, überlasse ich Dir zur Übung :wink:


Andreas

Vielen Dank für die Tipps !!!

Habe die ersten SQL-Abfragen mit Substrings ergänzt … funktioniert prima :slight_smile: .

Stellt sich nur noch die Frage, welche Lösung in Bezug auf die Performance am besten ist. Wie verhalten sich denn char[] zu “normalen” char()-Feldern mit Substring in der Abfrage bezüglich der Geschwindigkeit ?!

Andreas

probier es aus.

test=*# explain analyse select * from words where substring(w,1,1) = 'f';
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Seq Scan on words  (cost=0.00..17595.80 rows=3089 width=134) (actual time=380.710..617.406 rows=6930 loops=1)
   Filter: ("substring"(w, 1, 1) = 'f'::text)
 Total runtime: 630.414 ms
(3 rows)

Time: 631.382 ms
test=*# explain analyse select * from words where w_array[1] = 'f';
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Seq Scan on words  (cost=0.00..16051.50 rows=3089 width=134) (actual time=346.324..562.338 rows=6930 loops=1)
   Filter: (w_array[1] = 'f'::bpchar)
 Total runtime: 575.402 ms
(3 rows)

w_array enthält das, was in w als text steht, als char.


Andreas