Ich habe einen View, der aus mehreren unions zusammengewürfelt ist.
jetzt habe ich folgendes Problem:
create view v_view as
select svalue1 from t1
union all
select svalue2 from t2
In t1 und t2 ist das feld svalue1/svalue2 als varchar(8) deklariert.
Wenn ich das obige statement zu einem view mache, und dann ein select svalue from v_view ausführe, ist svalue von zwar noch varchar, aber es hat eine Feldlänge, die größer als 255 ist…
Kann mir einer einen Tip geben wie es am einfachsten zu realisieren ist, dass das Ergebnis ebenfalls varchar(8) ist?
eine Methode, die aber sehr unpraktisch ist, wäre es, in jedem statement das Feld einzeln zu casten:
create view v_view as
select cast( svalue1 as varchar(8) ) from t1
union all
select cast( svalue2 as varchar(8) ) from t2
Da ich aber insgesamt 4 unions mit jeweils 28 Spalten habe, ist das seeeehr aufwendig.
Gibt es da nicht eine bessere Lösung?
Kann man nicht dem View direkt mitteilen welche Spalte er als welchen Datentyp zu behandeln hat?
meine programmiersprache kennt bei Variablen den Typ
STRING (weniger als 255 Zeichen)
und
LONGSTRING (x-beliebig viele Zeichen)
Wir haben einen gekauften Klassen-Generator, der einen view auslesen kann und entsprechend der Feldlänge dann entscheidet, ob die Variablen der einzelnen Spalten als STRING oder LONGSTRING zu deklarieren sind.
Leider gibt es aber das Problem, dass in Child-Table-Windows (Anzeigeobjekte für Tabellendaten) die LONGSTRING-Variablen einigen Ärger bereiten.
Daher müsste ich die Viewfelder als STRING und nicht als LONGSTRING vorliegen haben.
Leider kann ich nicht die Programmklasse “überlisten”, indem ich aus den entsprechenden variablen STRING statt LONGSTRING mache, weil ja dann die Felder nicht mehr eingelesen werden…
Hoffe das war verständlich…
es ist dann varchar, ohne Begrenzung.
Könnte mann denn der Postgre mitteilen, dass der Default statt “varchar, ohne Begrenzung” lieber varchar (254) sein soll?
Dann könnte ich ja im Ausnahmefall immer noch einen Cast auf solche Objekte machen, die größer als 255 sind.
Varchar ohne Begrenzung erhält man bei einer UNION von Tabellen als Ergebnistyp nur, wenn die Spalten in den einzelnen Tabellen unterschiedliche Länge haben.
Behauptung, ohne sachlichen fachlichen Nachweis irgeneiner Art, zudem unlogisch.
drop table
if exists t1 CASCADE;
create table t1
(
s1 varchar(8),
a1 int
);
insert into t1 values ('abcdefgh', 5);
drop table
if exists t2 CASCADE;
create table t2
(
s2 varchar(8),
a2 int
);
insert into t2 values ('123', 3);
create view v1 as
select * from t1
union all
select * from t2;
select * from v1;
Nein. Den Nachweis erbrachte ja übrigens auch schon der Fragesteller. Aber für Dich hier noch einmal:
[php]
test=# create table h1 (t varchar(8));
CREATE TABLE
test=# create table h2 (t varchar(8));
CREATE TABLE
test=# create view h as select * from h1 union all select * from h2;
CREATE VIEW
test=*# \d h
View “public.h”
Column | Type | Modifiers
--------±------------------±----------
t | character varying |
View definition:
SELECT h1.t
FROM h1
UNION ALL
SELECT h2.t
FROM h2;
[/php]
Muss wohl an pgAdmin liegen!
Da könntest Du Recht haben. Vielleicht fragt es ja noch einmal die beteiligten Tabellen ab. Außerdem kommt es da noch auf die Version von PG an, 8.2 ist da besser als 8.1.
Ich erlaube mir auch mal, ein Zitat einer Mail von Tom Lane hier einzufügen:
[php]
As i said in a private mail to Scott (sorry): the suggested way don’t
work, at least with 8.1. Maybe this works better in more recent
versions.
Yes, it works a lot better in 8.2:
If you really need the right output type in 8.1, you could force the
issue with an extra level of sub-select:
regression=# create table foo (f1 varchar(8));
CREATE TABLE
regression=# create view voo as select f1::varchar(8) from (select * from foo union select * from foo) ss;
CREATE VIEW
regression=# \d voo
View “public.voo”
Column | Type | Modifiers
--------±---------------------±----------
f1 | character varying(8) |
View definition:
SELECT ss.f1::character varying(8) AS f1
FROM ( SELECT foo.f1
FROM foo
UNION
SELECT foo.f1
FROM foo) ss;
Nein, das immer noch eine Problembeschreibung. Die wichtigste Angabe, mit welcher PostgreSQL-Version er arbeitet, fehlt. Da das Problem Versionsabhängig ist, ist eine pauschale Antwort nicht eindeutig.
Gute Idee. Es gilt aber immer noch, was bei Datenbanken immer gültig war: Alle notwendigen Information stehen in den Systemtabellen und pgAdmin holt sich daher die Information des Ergebnistyps aus den Systemtabellen.
Ja, auf die Version kommt es an. 8.1 und 8.2 verhalten sich, wie ich es beschrieben habe, vor 8.1 gilt Deine Version.