view-spalten aus mehrerene unions einmalig casten

Servus,

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?

Gruß
Ingo

es ist dann varchar, ohne Begrenzung.

Kann mir einer einen Tip geben wie es am einfachsten zu realisieren ist, dass das Ergebnis ebenfalls varchar(8) ist?

Welches Problem hast Du damit? Vielleicht fällt mir dann was ein…

Andreas

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.

Hallo Ingo,

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.



mfg

fristo

Nein.

Andreas

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;



Für “s2 varchar(8)” erhält man

[ATTACH]28[/ATTACH]



Für “s2 varchar(9)” erhält man

[ATTACH]29[/ATTACH]



Muss wohl an pgAdmin liegen!





mfg

fristo

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:
http://archives.postgresql.org/pgsql-committers/2006-08/msg00222.php

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;


regards, tom lane
[/php]


Andreas

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.





mfg

fristo

Nein. Das, was ich gezeigt habe, war 8.1.

Andreas