Re: Longueur des colonnes char dans une view RESOLU

From: <c(dot)maumont(at)univitis(dot)fr>
To: "Ludovic Levesque" <luddic(at)gmail(dot)com>
Cc: <pgsql-fr-generale(at)postgresql(dot)org>
Subject: Re: Longueur des colonnes char dans une view RESOLU
Date: 2010-01-14 09:46:50
Message-ID: 5396D5718EFD454CA8764251327595E147CC26@EVS01.hexv2.local
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

Bonjour,

La view tuv1 ne marche pas, mais BINGO !! tuv2 fonctionne.

Ca c'est du contournement !

Il semble donc bien qu'il y ait un bug en 8.1.

Je vais envisager sérieusement l'upgrade en 8.4, mais en attendant ça me sort une sacrée épine du pied.

Merci à tous pour votre aide.

Christophe

> -----Message d'origine-----
> De : Ludovic Levesque [mailto:luddic(at)gmail(dot)com]
> Envoyé : jeudi 14 janvier 2010 10:37
> À : Christophe Maumont (c(dot)maumont(at)univitis(dot)fr)
> Cc : pgsql-fr-generale(at)postgresql(dot)org
> Objet : Re: [pgsql-fr-generale] Longueur des colonnes char dans une
> view
>
> Bonjour,
>
> je n'ai pas pu tester sur une 8.1, mais sur une 8.3.
>
> Peut-être en forçant un SELECT au dessus de l'UNION, voir tuv2:
>
> CREATE TABLE t(c50 character(50));
>
> CREATE OR REPLACE VIEW tuv1 AS
> SELECT 'R'::character(1) AS t_vw_essai, t.c50::character(1) as f1,
> t.c50::character(50) as f50
> FROM t
> UNION
> SELECT 'R'::character(1) AS t_vw_essai, t.c50::character(1) as f1,
> t.c50::character(50) as f50
> FROM t;
>
> CREATE OR REPLACE VIEW tuv2 AS
> SELECT t_vw_essai::character(1), f1::character(1),
> f50::character(50)
> FROM (
> SELECT 'R'::character(1) AS t_vw_essai, t.c50::character(1) as
> f1, t.c50::character(50) as f50
> FROM t
> UNION
> SELECT 'R'::character(1) AS t_vw_essai, t.c50::character(1) as
> f1, t.c50::character(50) as f50
> FROM t
> ) as tmp
> ;
>
> select table_name, column_name, character_maximum_length from
> information_schema.columns where table_name IN ('t', 'tuv1', 'tuv2');
> table_name | column_name | character_maximum_length
> ------------+-------------+--------------------------
> t | c50 | 50
> tuv1 | t_vw_essai | 1
> tuv1 | f1 | 1
> tuv1 | f50 | 50
> tuv2 | t_vw_essai | 1
> tuv2 | f1 | 1
> tuv2 | f50 | 50
> (7 rows)
>
>
> Ludo
>
>
> 2010/1/14 <c(dot)maumont(at)univitis(dot)fr>:
> >> >>>
> >> >>> Bonjour,
> >> >>>
> >> >>> Quand je crée une view, les colonnes en integer ou numeric sont
> >> bien
> >> >>> caractérisée dans information_schema.columns en terme de
> précision.
> >> >>>
> >> >>> Par contre, les colonnes en char(x) dans les tables d'origine
> >> >>> apparaissent avec character_maximum_length non renseigné.
> >> >>>
> >> >>> Est-il possible de fixer cette longueur ?
> >> >>>
> >> >>> Actuellement je crée ma view avec :
> >> >>>
> >> >>> CREATE OR REPLACE VIEW vw_essai
> >> >>> (
> >> >>>   t_vw_essai,
> >> >>>   n_ent_cmd,
> >> >>>   soc,
> >> >>>   ref_cli,
> >> >>>   mt_ht
> >> >>> )
> >> >>> as
> >> >>> select 'R'::char(1),n_ent_cmd,soc,ref_cli,mt_ht from ent_res
> >> >>> union
> >> >>> select 'M'::char(1),n_ent_cmd,soc,ref_cli,mt_ht from ent_mch;
> >> >>>
> >> >>> n_ent_cmd est un integer, soc un char(1), ref_cli un char(50) et
> >> >> mt_ht
> >> >>> un numeric(12,2).
> >> >>>
> >> >>> Postgresql 8.1 sur DEBIAN/ETCH
> >> >>>
> >> >> J'ai peut-être mal compris ta question, en tout cas je n'arrives
> pas
> >> à
> >> >> reproduire ton problème avec un serveur PG 8.2.x :
> >> >>
> >> >> create table txt_7 (n_ent_cmd integer,soc char(1),ref_cli
> char(50));
> >> >>
> >> >> create view v_txt7 (t_vw_essai,n_ent_cmd,soc,ref_cli)
> >> >> as select 'R'::char(1),n_ent_cmd,soc,ref_cli from txt_7;
> >> >>
> >> >> select table_name, column_name, character_maximum_length
> >> >> from information_schema.columns
> >> >> where column_name IN ('soc','ref_cli');
> >> >>
> >> >>  table_name | column_name | character_maximum_length
> >> >> ------------+-------------+--------------------------
> >> >>  txt_7      | soc         |                        1
> >> >>  txt_7      | ref_cli     |                       50
> >> >>  v_txt7     | soc         |                        1
> >> >>  v_txt7     | ref_cli     |                       50
> >> >>
> >> >> Est-ce bien c'est le résultat que tu attends ?
> >> >>
> >> >> --
> >> >> damien
> >> >
> >> > C'est exactement ce que je voudrais, mais j'obtiens la colonne
> >> character_maximum_length à null.
> >> > Si je ne mets pas d'union dans la vue, j'obtiens la même chose que
> >> toi (merci damien, tu as fais avancer mon schmilblick),
> >> > ma 8.1 fonctionne donc comme ta 8.2 sur ce point, c'est déjà ça.
> >> > Le problème viendrais donc de l'union, il semble que postgresql ne
> >> sache pas quelle longueur prendre pour les char(x) dans ce cas.
> >> >
> >> > La question est donc de savoir si le problème est propre à ma
> version
> >> et si il y a une syntaxe particulière du CREATE VIEW permettant de
> >> forcer ces longueurs.
> >> >
> >>
> >> Pas mieux,
> >>
> >> create table txt_8 (n_ent_cmd integer,soc char(1),ref_cli char(50));
> >>
> >> create view v_txt8 (t_vw_essai,n_ent_cmd,soc,ref_cli)
> >> as select 'R'::char(1),n_ent_cmd,soc,ref_cli from txt_7
> >> union select 'M'::char(1),n_ent_cmd,soc,ref_cli from txt_8;
> >>
> >> select table_name, column_name, character_maximum_length
> >> from information_schema.columns where column_name IN
> ('soc','ref_cli');
> >>
> >>  table_name | column_name | character_maximum_length
> >> ------------+-------------+--------------------------
> >>  txt_7      | soc         |                        1
> >>  txt_7      | ref_cli     |                       50
> >>  v_txt7     | soc         |                        1
> >>  v_txt7     | ref_cli     |                       50
> >>  txt_8      | soc         |                        1
> >>  txt_8      | ref_cli     |                       50
> >>  v_txt8     | soc         |                        1
> >>  v_txt8     | ref_cli     |                       50
> >>
> >>
> >> Par contre, si les deux tables n'ont pas le même schéma. Exemple :
> >>
> >> create table txt_9 (n_ent_cmd integer,soc char(10),ref_cli varchar);
> >>
> >> create view v_txt9 (t_vw_essai,n_ent_cmd,soc,ref_cli)
> >> as select 'R'::char(1),n_ent_cmd,soc,ref_cli from txt_9
> >> union select 'M'::char(1),n_ent_cmd,soc,ref_cli from txt_8;
> >>
> >> select table_name, column_name, character_maximum_length
> >> from information_schema.columns where column_name IN
> ('soc','ref_cli');
> >>
> >>  table_name | column_name | character_maximum_length
> >> ------------+-------------+--------------------------
> >>  txt_7      | soc         |                        1
> >>  txt_7      | ref_cli     |                       50
> >>  v_txt7     | soc         |                        1
> >>  v_txt7     | ref_cli     |                       50
> >>  txt_8      | soc         |                        1
> >>  txt_8      | ref_cli     |                       50
> >>  v_txt8     | soc         |                        1
> >>  v_txt8     | ref_cli     |                       50
> >>  txt_9      | soc         |                       10
> >>  txt_9      | ref_cli     |
> >>  v_txt9     | soc         |
> >>  v_txt9     | ref_cli     |
> >>
> >> A priori les colonnes CHAR de tes tables ent_res et ent_mch n'ont
> pas
> >> la
> >> même longuer... Du coup j'imagine que PostgreSQL converti à la volée
> le
> >> type des colonnes en VARCHAR.
> >>
> >> Si les colonnes que tu veux unir ne sont pas homogènes, tu peux
> >> simplement "forcer" leur taille avec un cast explicite. Par exemple
> >> pour
> >> la colonne soc:
> >>
> >> CREATE OR REPLACE VIEW vw_essai (...) as
> >> select 'R'::char(1),n_ent_cmd,soc::char(42),ref_cli,mt_ht from
> ent_res
> >> union
> >> select 'M'::char(1),n_ent_cmd,soc::char(42),ref_cli,mt_ht from
> ent_mch;
> >
> > J'essaye donc :
> >
> > CREATE OR REPLACE VIEW vw_essai AS
> >  SELECT 'R'::character(1) AS t_vw_essai, ent_res.soc::character(1),
> ent_res.ref_cli::character(50)
> >   FROM ent_res
> > UNION
> >   SELECT 'R'::character(1) AS t_vw_essai, ent_res.soc::character(1),
> ent_res.ref_cli::character(50)
> >   FROM ent_res;
> >
> > select table_name, column_name, character_maximum_length from
> information_schema.columns where table_name IN ('ent_res','vw_essai')
> and column_name IN ('t_vw_essai','soc','ref_cli');
> >
> > et j'obtiens :
> >
> > table_name | column_name | character_maximum_length
> > ------------+-------------+--------------------------
> >  ent_res    | soc         |                        1
> >  ent_res    | ref_cli     |                       50
> >  vw_essai   | t_vw_essai  |
> >  vw_essai   | soc         |
> >  vw_essai   | ref_cli     |
> >
> > Même en faisant l'union sur la même table (les colonnes ont donc la
> même longueur) et en forçant le cast, ça ne marche pas.
> > On dirait un bug, est-il propre à la 8.1 ?
> > Je suis près à passer à une version supérieure (8.4) mais seulement
> si ça corrige le problème,
> > sinon ma 8.1 me convient parfaitement.
> >
> > Y-a-t-il une syntaxe qui permettrait de caster les colonnes de la
> view (je n'ai rien trouvé dans la doc), un truc du genre :
> >
> > CREATE OR REPLACE VIEW vw_essai
> > (
> > t_vw_essai char(1),
> > soc char(1),
> > ref_cli char(50)
> > )
> >
> >  AS
> >  SELECT 'R'::character(1) AS t_vw_essai, ent_res.soc::character(1),
> ent_res.ref_cli::character(50)
> >   FROM ent_res
> > UNION
> >   SELECT 'R'::character(1) AS t_vw_essai, ent_res.soc::character(1),
> ent_res.ref_cli::character(50)
> >   FROM ent_res;
> >
> > Merci pour l'aide.
> >
> >
> >
> >
> >
> >
> >
> > --
> > Sent via pgsql-fr-generale mailing list (pgsql-fr-
> generale(at)postgresql(dot)org)
> > To make changes to your subscription:
> > http://www.postgresql.org/mailpref/pgsql-fr-generale
> >

In response to

Browse pgsql-fr-generale by date

  From Date Subject
Next Message damien clochard 2010-01-20 08:20:49 Comment traduire "Streaming Réplication" ?
Previous Message damien clochard 2010-01-14 09:45:16 Re: Longueur des colonnes char dans une view