Re: Longueur des colonnes char dans une view

From: damien clochard <damien(at)dalibo(dot)info>
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-13 11:35:30
Message-ID: 4B4DB002.4080102@dalibo.info
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

c(dot)maumont(at)univitis(dot)fr a écrit :
> Rebonjour,
>
> Oups ! Erreur d'aiguillage, un copier/coller malheureux.
> Merci d'avoir corrigé.
>
> La suite plus bas.
>
>> -----Message d'origine-----
>> De : damien clochard [mailto:damien(at)dalibo(dot)info]
>> Envoyé : mercredi 13 janvier 2010 11:02
>> À : Stéphane Schildknecht
>> Cc : 'pgsql-fr-generale(at)postgresql(dot)org'; Christophe Maumont
>> (c(dot)maumont(at)univitis(dot)fr)
>> Objet : Re: [pgsql-fr-generale] Longueur des colonnes char dans une
>> view
>>
>> Stéphane Schildknecht a écrit :
>>> Bonjour,
>>>
>>> Ci-joint un message adressé par erreur à l'administrateur et non à la
>> liste.
>>> Merci de conserver Christophe en copie, car je ne sais pas s'il est
>>> abonné à la liste.
>>>
>>> #####
>>>
>>> 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;

In response to

Browse pgsql-fr-generale by date

  From Date Subject
Next Message c.maumont 2010-01-14 08:58:34 Re: Longueur des colonnes char dans une view
Previous Message c.maumont 2010-01-13 10:26:01 Re: Longueur des colonnes char dans une view