1 Stimmen

Ist es in Ordnung, ASCII-Dezimalzeichen in einer Postgres-SELECT-Abfrage einzufügen?

Ich benötige den Ausgang einer SELECT-Anweisung auf diese Weise.

Sie sind den folgenden Projekten zugewiesen:

  • A
  • B
  • C

Es gibt einige Leerzeichen, Sonderzeichen und Zeilenumbrüche. Um das zu erreichen, habe ich ASCII-Zeichen chr(10), chr(32), chr(8226) verwendet. Es funktioniert gut, aber die Abfrage sieht nicht gut aus und ich bin mir nicht sicher, ob es ein guter Ansatz ist, es so zu tun. Die Abfrage sieht so aus:

SELECT 
'Sie sind den folgenden Projekten zugewiesen:' || chr(10) || chr(32) || chr(8226) || chr(32) ||
string_agg(e.projects, chr(10) || chr(32) || chr(8226) || chr(32))

Wird das auch in allen Betriebssystemen und in jeder Umgebung funktionieren?

3voto

Craig Ringer Punkte 280068

Sie haben einige Möglichkeiten:

  • Fügen Sie Zeichen wörtlich ein. Normalerweise die beste Option. Möchten Sie ein "•"? Verwenden Sie einen String wie 'this is a •'. Es ist nichts weiter erforderlich, wenn Ihre client_encoding korrekt ist und die Codierung, die Sie verwenden, das gewünschte Zeichen enthält (wie ). Dies ist SQL-Standard. Zeilenumbrüche können als Literale eingeschlossen werden:

    SELECT '
    ' AS "this_is_a_newline";

    Diese Methode funktioniert möglicherweise nicht für einige nicht druckbare Zeichen, abhängig von der Datenbankimplementierung. Für PostgreSQL funktioniert dies für alles, außer \x00, dem Nullbyte, das PostgreSQL nicht in text / varchar usw. unterstützt, sondern nur in bytea.

    Achten Sie darauf, dass die Textcodierung Ihres Texteditors / SQL-Editors mit dem übereinstimmt, was Ihre Verbindung PostgreSQL als client_encoding angibt, da Sie sonst fehlerhafte Zeichenfolgen oder seltsame Fehler erhalten. Benutzer von Unix-ähnlichen Terminals müssen auch sicherstellen, dass die Terminalcodierung mit client_encoding übereinstimmt, um seltsame Ausgabefehler zu vermeiden. Heutzutage ist Windows die einzige Plattform, bei der dies in der Regel ein Problem darstellt.

  • Fügen Sie Zeichen über hexadezimale oder Unicode-Literale in einem E'' Escape-String ein, z.B. E'this is a \u2022'. Beachten Sie, dass \u Escape-Sequenzen hexadezimal sind - 0x2022 entspricht dezimal 8226. Die Syntax von E'' ist eine PostgreSQL-Erweiterung.

  • Verwenden Sie für Zeichen, für die Kurzformescapes definiert sind, die Kurzformescapes in einem Escape-String, z.B. E'\n'. Dies ist eine PostgreSQL-Erweiterung.

  • Verwenden Sie chr(8226), wie Sie beschrieben haben, aber beachten Sie, dass chr den Code gemäß Ihrer server_encoding (der Textcodierung der Datenbank) interpretiert. Daher ermutige ich dies nicht. Für mehrbyte Zeichen erhalten Sie einfach einen Fehler wie FEHLER: angefordertes Zeichen ist für Codierung zu groß: 8226:

      regress=> CREATE DATABASE latin ENCODING 'latin-1' LC_CTYPE 'C' LC_COLLATE 'C' TEMPLATE template0;
      CREATE DATABASE
      regress=> \c latin
      Sie sind jetzt mit der Datenbank "latin" als Benutzer "craig" verbunden.
      lateinisch=> SHOW server_encoding;
       server_encoding 
      -----------------
       LATIN1
      (1 Zeile)
    
      lateinisch=> SHOW client_encoding;
       client_encoding 
      -----------------
       UTF8
      (1 Zeile)
      lateinisch=> select chr(8226);
      FEHLER:  angefordertes Zeichen ist für Codierung zu groß: 8226

    aber für Zeichen, deren Ordinal im 1-Byte-Bereich liegt, erhalten Sie stattdessen ein unerwartetes Zeichen. Nehmen Sie ü, das sowohl in utf-8 als auch in latin-1 (iso-8859-1) 0xfc ist (dezimal 252), aber in iso-8859-5 ist. Also:

     regress=> SHOW server_encoding;
     server_encoding 
     -----------------
     UTF8
    
     regress=> SELECT chr(252);
     chr 
     -----
      ü
    
     regress=> CREATE DATABASE iso5 ENCODING 'iso-8859-5' LC_CTYPE 'C' LC_COLLATE 'C' TEMPLATE template0;
    
     regress=> \c iso5
    
     iso5=> SELECT chr(252);
     chr 
    -----

Also mein Rat: Verwenden Sie immer Literale, wo immer möglich. Wenn Sie Escape-Sequenzen verwenden müssen, verwenden Sie E'' Strings mit Unicode-Escapes, um Unklarheiten über die Bedeutung eines Codepunkts basierend auf der aktuellen Servercodierung zu vermeiden. Vermeiden Sie \x Escapes und chr.

Für Ihr spezifisches Beispiel sollten Sie folgendes verwenden:

SELECT 'Sie sind folgenden Projekten zugeordnet:

    • A
    • B
    • C';

Hinweis für Leser auf sehr alten PostgreSQL-Versionen: Sehr alte PostgreSQL-Versionen unterstützten keine E''-Zeichenfolgen und behandelten alle Zeichenfolgen, als wären sie Escape-Zeichen. Also bedeutete '\n' "Zeilenumbruch", während modernes PostgreSQL dem SQL-Standard folgt, bei dem '\n' einfach die Zeichenfolge "\n" ist. Nur marginal prähistorische Versionen haben dies immer noch getan, aber eine Warnung dazu ausgegeben und es Ihnen ermöglicht, das Standardverhalten zu fordern, indem Sie standard_conforming_strings = on setzten. Dies ist schon seit geraumer Zeit der Standard.

1voto

zerkms Punkte 239362

Statt

chr(10) || chr(32) || chr(8226) || chr(32)

verwenden Sie einfach

\n • 

Kein Grund, in diesem Fall chr() zu verwenden.

Bildbeschreibung hier eingeben

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X