sql >> Database >  >> RDS >> PostgreSQL

Kolomnamen met regeleinden

Kolomnamen zijn id's en de bloederige details van de syntaxis voor id's worden beschreven op:

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

TL;DR :gebruik de U&"..." syntaxis om niet-afdrukbare tekens in identifiers te injecteren via hun Unicode-codepunten, en er is geen manier om CR,LF te verenigen met LF alleen.

Hoe te verwijzen naar de kolom in een enkele regel

We mogen Unicode-escape-reeksen gebruiken in identifiers, dus volgens documentatie werkt het volgende:

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

als het slechts een teken van een nieuwe regel is tussen de twee woorden.

Wat gebeurt er met de vragen op de eerste tafel

De tabel is gemaakt met:

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

Omdat de backslash hier geen speciale betekenis heeft, bevat deze kolom geen nieuwe regel. Het bevat first gevolgd door \ gevolgd door n gevolgd door second .Dus:

 SELECT "first\nsecond" from One;

werkt wel omdat het hetzelfde is als in de CREATE TABLE

overwegende dat

SELECT "first
second" from One;

mislukt omdat er een nieuwe regel in die SELECT is waar de werkelijke kolomnaam in de tabel een backslash heeft gevolgd door een n .

Wat gebeurt er met de vragen op de tweede tafel

Dit is het tegenovergestelde van "One".

CREATE TABLE Two("first
second" text);

De nieuwe regel wordt letterlijk genomen en maakt deel uit van de kolom.Dus

SELECT "first
second" from Two;

werkt omdat de nieuwe regel er precies is zoals in de CREATE TABLE, met een ingesloten nieuwe regel, terwijl

SELECT "first\nsecond" from Two;

mislukt omdat zoals eerder \n in deze context betekent niet een nieuwe regel.

Carriage Return gevolgd door Newline, of iets vreemds

Zoals vermeld in opmerkingen en uw bewerking, zou dit in plaats daarvan een regelterugloop en een nieuwe regel kunnen zijn, in welk geval het volgende zou moeten voldoen:

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

hoewel ik in mijn test op Enter in het midden van een kolom drukte met psql op Unix en Windows heeft hetzelfde effect:een enkele nieuwe regel in de naam van de kolom.

Om te controleren welke exacte tekens in een kolomnaam zijn terechtgekomen, kunnen we ze in hexadecimaal inspecteren.

Wanneer toegepast op uw voorbeeld van een tabel maken, vanuit psql onder 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';

Het resultaat is:

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

Voor complexere gevallen (bijv. niet-ascii-tekens met meerdere bytes in UTF-8), kan een meer geavanceerde query helpen, voor gemakkelijk leesbare codepunten:

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



  1. Waarden samenvoegen op basis van ID

  2. SqlAlchemy retourneert niet alle rijen bij het opvragen van tabelobjecten, maar retourneert alle rijen wanneer ik de tabelobjectkolom opvraag

  3. Een slechte database herstructureren met PHP-loops of MySQL

  4. Hoe 'select' te gebruiken in MySQL 'insert' statement