programing

Oracle - TO_CHAR로 변환할 때 선두 0이 사라지는 이유는 무엇입니까?

copyandpastes 2023. 3. 15. 23:27
반응형

Oracle - TO_CHAR로 변환할 때 선두 0이 사라지는 이유는 무엇입니까?

Oracle에서는 선행 0의 숫자를 문자로 변환할 때 선행 번호가 사라지는 이유는 무엇입니까?이 논리는 Oracle 고유합니까, 아니면 SQL 고유합니까?

예:

SELECT TO_CHAR(0.56) FROM DUAL;
/* Result = .56 */

선두 또는 후행 공백, 마침표, 0(존재해야 할 1보다 작은 숫자에 대해서는 선두 0을 제외함)을 사용하지 않고 숫자를 포맷하는 방법을 찾고 있었습니다.

Oracle에서는 이러한 일반적인 포맷을 쉽게 수행할 수 없다는 점이 불만입니다.

Tom Kyte조차 다음과 같은 길고 복잡한 회피책을 제안했습니다.

case when trunc(x)=x
    then to_char(x, 'FM999999999999999999')
    else to_char(x, 'FM999999999999999.99')
end x

단 한 번만 가치를 언급하는 짧은 솔루션을 찾을 수 있었습니다.

rtrim(to_char(x, 'FM999999999999990.99'), '.')

이것은 가능한 모든 값에 대해 예상대로 동작합니다.

select 
    to_char(num, 'FM99.99') wrong_leading_period,
    to_char(num, 'FM90.99') wrong_trailing_period,
    rtrim(to_char(num, 'FM90.99'), '.') correct
from (
  select num from (select 0.25 c1, 0.1 c2, 1.2 c3, 13 c4, -70 c5 from dual)
  unpivot (num for dummy in (c1, c2, c3, c4, c5))
) sampledata;

    | WRONG_LEADING_PERIOD | WRONG_TRAILING_PERIOD | CORRECT |
    |----------------------|-----------------------|---------|
    |                  .25 |                  0.25 |    0.25 |
    |                   .1 |                   0.1 |     0.1 |
    |                  1.2 |                   1.2 |     1.2 |
    |                  13. |                   13. |      13 |
    |                 -70. |                  -70. |     -70 |

아직 더 짧은 솔루션을 찾고 있습니다.

커스텀 헬퍼 기능을 갖춘 쇼트닝 어프로치(accessarch)가 있습니다.

create or replace function str(num in number) return varchar2
as
begin
    return rtrim(to_char(num, 'FM999999999999990.99'), '.');
end;

그러나 커스텀 pl/sql 함수는 대량의 쿼리에 적합하지 않은 상당한 성능 오버헤드가 있습니다.

이는 Oracle에서 제공하는 기본 포맷입니다.출력에 선행 0을 사용하려면 형식을 명시적으로 지정해야 합니다.용도:

SELECT TO_CHAR(0.56,'0.99') FROM DUAL;

또는 다음과 같은 경우도 있습니다.

SELECT TO_CHAR(.56,'0.99') FROM DUAL;

후행 제로도 마찬가지입니다.

SQL> SELECT TO_CHAR(.56,'0.990') val FROM DUAL;

VAL
------
 0.560

TO_CHAR 변환 함수의 일반적인 형식은 다음과 같습니다.

TO_CHAR(숫자, 형식)

예쁜 십진수를 얻는 유일한 방법은 말도 안 되는 코드가 필요한 것 같아요.

지금까지 내가 얻은 유일한 해결책은:

CASE WHEN xy>0 and xy<1 then '0' || to_char(xy) else to_char(xy)

xy는 소수입니다.

xy             query result
0.8            0.8  --not sth like .80
10             10  --not sth like 10.00

그것은 1보다 작은 숫자에 대해서만 유효합니다.

select to_char(12.34, '0D99') from dual;
-- Result: #####

이거 안 되겠다.

다음과 같은 작업을 수행할 수 있지만 결과적으로 선행 공백이 발생합니다.

select to_char(12.34, '999990D99') from dual;
-- Result: '     12,34'

최종적으로, TRIM을 추가해 화이트 스페이스를 없앨 수 있지만, 그것 또한 적절한 해결책이라고는 생각하지 않습니다.

select trim(to_char(12.34, '999990D99')) from dual;
-- Result: 12,34

다시 말씀드리지만, 이 기능은 최대 6자리 숫자에 대해서만 작동합니다.

편집 : Dcookie의 제안에 대한 코멘트로 추가하고 싶었지만 할 수 없습니다.

to_char 제한을 피하려면 다음 절차를 수행합니다.

SELECT 
regexp_replace(regexp_replace(n,'^-\'||s,'-0'||s),'^\'||s,'0'||s)
FROM (SELECT -0.89 n,RTrim(1/2,5) s FROM dual);

모든 경우에 사용할 수 있습니다.

SELECT regexp_replace(0.1234, '^(-?)([.,])', '\10\2') FROM dual

아래 형식에서 숫자가 다음과 같은 경우 시도합니다.

ex 1 아래에 10.1과 같은 숫자가 적용되면 10.10이 된다고 가정합니다.

ex 2 .02와 같은 숫자가 아래에 적용되면 0.02가 된다고 가정합니다.

ex 3 아래 형식에 적용되는 경우 0.2와 같은 숫자가 0.20이 된다고 가정합니다.

to_char(round(to_number(column_name)/10000000,2), '9999999990D99'는 column_name으로 지정됩니다.

국가에서 10진수로 콤마를 지원하는 경우 다음을 사용합니다.

SELECT regexp_replace(
            regexp_replace(to_char(YOUR_NUMBER), '^,', '0,'), -- Positives
            '^-,', '-0,') -- Negatives

그 이외의 경우는, 10 진수의 닷을 서포트하고 있는 경우는, 다음과 같이 해 주세요.

SELECT regexp_replace(
            regexp_replace(to_char(YOUR_NUMBER), '^.', '0.'), -- Positives
            '^-.', '-0.') -- Negatives

언급URL : https://stackoverflow.com/questions/6695604/oracle-why-does-the-leading-zero-of-a-number-disappear-when-converting-it-to-c

반응형