2015-09-23 11 views
5

Ich verwende die TO_CHAR Funktion Format Anzahl von 0001 zu 9999, und die Spaltengröße zu passen (VARCHAR2(4)), wo der Wert eingefügt wird (auch wenn Wert> 9999).Oracle to_char Formatnummer mit Füllmodus (FM0000)

Ich verwende die Funktion wie folgt aus:

TO_CHAR(n, 'FM0000') 

Beispiele, die funktionieren:

SELECT TO_CHAR(1, 'FM0000') FROM DUAL; 

Ergebnis: 0001

SELECT TO_CHAR(1234, 'FM0000') FROM DUAL; 

Ergebnis: 1234

Aber wenn ich mit einem Wert testen größer als 9999, erhalte ich ein zusätzliches Zeichen:

SELECT TO_CHAR(12345, 'FM0000') FROM DUAL; 

Ergebnis: #####

SELECT TO_CHAR(123456, 'FM0000') FROM DUAL; 

Ergebnis: #####

Zur Information, das erwartete Ergebnis war #### (auf 4 Zeichen).

Zusammengefasst:

  • Wenn der Wert entspricht die erwartete Größe (4) zu überführen, hat der umgewandelte Wert mit der gleichen Länge (4)
  • Wenn der Wert mehr zu konvertieren, als die erwartete Größe (5 oder mehr), der konvertierte Wert hat ein Zeichen mehr als die erwartete Länge (5).

Wie dies zu erklären?

Ich habe nicht Erklärung in der Oracle-Dokumentation hier https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i170559

ich auf mehr Oracle-Version ausprobiert (9, 10, 11), und das Ergebnis ist das gleiche.

Die Abhilfe Ich fand ist das Ergebnis mit RPAD() Funktion RPAD(TO_CHAR(n,'FM0000'), 4) aber ich muss gestutzt verstehen, warum die TO_CHAR Funktion ist nicht genug.

+2

'TO_CHAR SELECT (-1, 'FM0000') FROM DUAL;' –

+1

Was genau sind Sie versuchen zu erreichen? Welchen Wert möchten Sie zurückgeben, wenn Sie eine Zahl größer als 9999 (zB 12345) auswählen? – Ollie

+1

Wenn Sie Ihre Abfrage mit <= 4 Ziffern in SQL \ * Plus ausführen, werden Sie feststellen, dass die Spaltenüberschrift immer mit fünf Zeichen "TO_CH" angezeigt wird. Es muss immer noch das Vorzeichen des Werts berücksichtigen, zusätzlich zu den vier signifikanten Ziffern, die Sie möchten. (Wie Florins Anfrage zeigt ...). Sie können es auch mit "FMS000" versuchen, um es explizit für positive Werte zu sehen. Sie könnten 'substr (to_char (...), -4)' als alternative Problemumgehung verwenden. –

Antwort

9

Ihr Formatmodell muss immer noch das Vorzeichen des Werts berücksichtigen. Es gibt keine Möglichkeit, zu TO_CHAR() anzuzeigen, dass es nie negativ sein kann (wenn das für Ihre Werte tatsächlich der Fall ist). Selbst mit einer 4-stelligen Zahl der Formatierung erlaubt fünf Zeichen erlaubt, wie man sich von der Spaltenüberschrift sehen:

SQL> SELECT TO_CHAR(1234, 'FM0000') FROM DUAL; 

TO_CH 
----- 
1234 

Beachten Sie die Spaltenüberschrift TO_CH ist, die fünf Zeichen sind, nicht vier.Wenn Sie eine negative Zahl haben (als Florin vorgeschlagen) benötigen Sie, dass mehr Platz:

SQL> SELECT TO_CHAR(-1234, 'FM0000') FROM DUAL; 

TO_CH 
----- 
-1234 

Ohne die FM Modifikator Sie einen führenden Platz im zurückgegebenen String für positive Werte zu erhalten, so LENGTH(TO_CHAR(1234, '0000')) 5 aber LENGTH(TO_CHAR(1234, 'FM0000')) 4, weil das führende Leerzeichen (das normalerweise die Werte in der Spalte rechtsbündig macht) unterdrückt wird. Bei einem negativen Wert beträgt die Länge der zurückgegebenen Zeichenfolge 5. Das Formatmodell legt fest, dass der zurückgegebene Datentyp varchar2(5) bis für das Zeichen zulässt, auch wenn Sie wissen, dass es nie negative Werte geben wird - es gibt keine Möglichkeit, dass das Formatmodell dies widerspiegelt.

Sie können es mit einem positiven Wert sehen, wenn Sie das Schild zwingen gezeigt werden:

SQL> SELECT TO_CHAR(1234, 'FMS0000') FROM DUAL; 

TO_CH 
----- 
+1234 

Es nicht alles, was Sie, dass etwa in dem TO_CHAR Anruf tun. Als Alternative zu Ihrem RPAD Problem zu umgehen, könnten Sie SUBSTR nur verwenden, um die letzten vier Zeichen des formatierten String zu erhalten:

SQL> SELECT SUBSTR(TO_CHAR(12345, 'FM0000'), -4) FROM DUAL 

SUBSTR(TO_CHAR(1 
---------------- 
#### 

Aber wenn Sie negative Werte zu tun haben würden Sie das Schild verlieren:

SQL> SELECT SUBSTR(TO_CHAR(-1234, 'FM0000'), -4) FROM DUAL 

SUBSTR(TO_CHAR(- 
---------------- 
1234 

Mit Ihrem RPAD Sie das Schild halten, aber die vierte signifikante Stelle verlieren:

SQL> SELECT RPAD(TO_CHAR(-1234, 'FM0000'), 4) FROM DUAL 

RPAD(TO_CHAR(-12 
---------------- 
-123 

die auch nicht gut ist. Sie müssen möglicherweise nicht mit negativen Zahlen umgehen; Aber wenn Sie mit einer größeren Zahl als erwartet arbeiten (dh Sie erhalten eine Zahl> = 10000, wenn Sie nur < = 9999 erwarten), dann bin ich mir nicht sicher, ob Sie sicher sein können, dass Sie kein (ungültiges?) Negative Nummer irgendwann auch. Dies scheint eher ein Datenproblem als ein Formatierungsproblem zu sein.


Basierend auf Ihren Kommentar zu Ollie, ein weiterer Ansatz, die deutlicher und offensichtlich für zukünftige Maintainer des Codes könnte sein, ist es in einem Fall zu buchstabieren:

SELECT CASE WHEN n BETWEEN 0 AND 9999 THEN TO_CHAR(n, 'FM0000') ELSE '####' END FROM DUAL 

die auch Sie erlauben würde, Um die Zeichenkettenspalte null zu lassen oder einen anderen magischen Wert als #### zu verwenden, wenn Sie wollten.

Und ein anderer Weg, um den Wert zu trimmen, die kann auch klarer sein, mit CAST ist:

SQL> SELECT CAST(TO_CHAR(12345, 'FM0000') AS VARCHAR2(4)) FROM DUAL; 

CAST 
---- 
#### 
Verwandte Themen