Skip site navigation (1) Skip section navigation (2)

Re: Longueur des colonnes char dans une view

From: <c(dot)maumont(at)univitis(dot)fr>
To: <pgsql-fr-generale(at)postgresql(dot)org>
Subject: Re: Longueur des colonnes char dans une view
Date: 2010-01-14 08:58:34
Message-ID: 5396D5718EFD454CA8764251327595E147CC1C@EVS01.hexv2.local (view raw or flat)
Thread:
Lists: pgsql-fr-generale
> >>>
> >>> 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.







Responses

pgsql-fr-generale by date

Next:From: Ludovic LevesqueDate: 2010-01-14 09:37:07
Subject: Re: Longueur des colonnes char dans une view
Previous:From: damien clochardDate: 2010-01-13 11:35:30
Subject: Re: Longueur des colonnes char dans une view

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group