From: | Ludovic Levesque <luddic(at)gmail(dot)com> |
---|---|
To: | c(dot)maumont(at)univitis(dot)fr |
Cc: | pgsql-fr-generale(at)postgresql(dot)org |
Subject: | Re: Longueur des colonnes char dans une view |
Date: | 2010-01-14 09:37:07 |
Message-ID: | 162718d41001140137h33208bcenad545d093d02557a@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-fr-generale |
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
>
From | Date | Subject | |
---|---|---|---|
Next Message | damien clochard | 2010-01-14 09:45:16 | Re: Longueur des colonnes char dans une view |
Previous Message | c.maumont | 2010-01-14 08:58:34 | Re: Longueur des colonnes char dans une view |