PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Noms de colonnes avec sauts de ligne

Les noms de colonne sont des identifiants, et les détails sanglants de la syntaxe des identifiants sont décrits à :

http://www.postgresql .org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

TL;DR :utilisez le U&"..." syntaxe pour injecter des caractères non imprimables dans les identifiants via leurs points de code Unicode, et il n'y a aucun moyen d'unifier CR,LF avec LF seul.

Comment faire référence à la colonne sur une seule ligne

Nous sommes autorisés à utiliser des séquences d'échappement Unicode dans les identifiants, donc selon la documentation, ce qui suit fonctionne :

select U&"first\000asecond" from Two;

s'il s'agit simplement d'un caractère de saut de ligne entre les deux mots.

Que se passe-t-il avec les requêtes sur la première table

Le tableau est créé avec :

CREATE TABLE One("first\nsecond" text);

Comme le caractère barre oblique inverse n'a pas de signification particulière ici, cette colonne ne contient pas de saut de ligne. Elle contient first suivi de \ suivi de n suivi de second .Alors :

 SELECT "first\nsecond" from One;

fonctionne car c'est la même chose que ce qui se trouve dans le CREATE TABLE

alors que

SELECT "first
second" from One;

échoue car il y a une nouvelle ligne dans ce SELECT où le nom de la colonne réelle dans la table a une barre oblique inverse suivie d'un n .

Que se passe-t-il avec les requêtes sur la deuxième table

C'est le contraire de "Un".

CREATE TABLE Two("first
second" text);

La nouvelle ligne est prise textuellement et fait partie de la colonne.Donc

SELECT "first
second" from Two;

fonctionne parce que la nouvelle ligne est là exactement comme dans CREATE TABLE, avec une nouvelle ligne intégrée, alors que

SELECT "first\nsecond" from Two;

échoue car comme précédemment \n dans ce contexte ne signifie pas une nouvelle ligne.

Retour chariot suivi d'une nouvelle ligne, ou de quelque chose de plus étrange

Comme mentionné dans les commentaires et votre modification, il peut s'agir d'un retour chariot et d'une nouvelle ligne, auquel cas ce qui suit devrait suffire :

select U&"first\000d\000asecond" from Two;

bien que dans mon test, appuyer sur Entrée au milieu d'une colonne avec psql sous Unix et Windows a le même effet :une seule nouvelle ligne dans le nom de la colonne.

Pour vérifier quels caractères exacts se sont retrouvés dans un nom de colonne, nous pouvons les inspecter en hexadécimal.

Lorsqu'il est appliqué à votre exemple de création de table, depuis l'intérieur de psql sous Unix :

CREATE TABLE Two("first
second" text);

select convert_to(column_name::text,'UTF-8')
 from information_schema.columns 
 where table_schema='public'
   and table_name='two';

Le résultat est :

        convert_to         
----------------------------
 \x66697273740a7365636f6e64

Pour les cas plus complexes (par exemple, des caractères non-ascii avec plusieurs octets en UTF-8), une requête plus avancée peut aider, pour des points de code faciles à lire :

select c,lpad(to_hex(ascii(c)),4,'0') from (
  select regexp_split_to_table(column_name::text,'')  as c
    from  information_schema.columns
    where table_schema='public'
    and table_name='two'
  ) as g;

 c | lpad 
---+------
 f | 0066
 i | 0069
 r | 0072
 s | 0073
 t | 0074
  +| 000a
   | 
 s | 0073
 e | 0065
 c | 0063
 o | 006f
 n | 006e
 d | 0064