programing

Oracle의 "숫자" 함수 확인

golfzon 2023. 3. 25. 12:04
반응형

Oracle의 "숫자" 함수 확인

oracle(10g) 쿼리의 컬럼 값이 수치인지 확인하고 비교하려고 합니다.예를 들어 다음과 같습니다.

select case when ( is_number(myTable.id) and (myTable.id >0) ) 
            then 'Is a number greater than 0' 
            else 'it is not a number' 
       end as valuetype  
  from table myTable

어떻게 확인할지 생각나는 거 없어?

여기에 기재되어 있는 또 하나의 아이디어는 정규 표현을 사용하여 다음 사항을 확인하는 것입니다.

SELECT  foo 
FROM    bar
WHERE   REGEXP_LIKE (foo,'^[[:digit:]]+$');

좋은 점은 별도의 PL/SQL 기능이 필요하지 않다는 것입니다.문제가 될 수 있는 부분은 정규식이 다수의 행에 대해 가장 효율적인 방법이 아닐 수 있다는 것입니다.

[ID]의 [myTable있을 이 있습니다).이는 (하여 '을 를 쓸 수 . 같은 거

CREATE OR REPLACE FUNCTION is_number( p_str IN VARCHAR2 )
  RETURN VARCHAR2 DETERMINISTIC PARALLEL_ENABLE
IS
  l_num NUMBER;
BEGIN
  l_num := to_number( p_str );
  RETURN 'Y';
EXCEPTION
  WHEN value_error THEN
    RETURN 'N';
END is_number;

그런 다음 해당 콜을 쿼리에 포함시킬 수 있습니다.

SELECT (CASE WHEN is_number( myTable.id ) = 'Y' AND myTable.id > 0 
               THEN 'Number > 0'
             ELSE 'Something else'
         END) some_alias
  FROM myTable

PL/SQL에는 부울 데이터 유형이 있지만 SQL에는 없습니다.따라서 부울을 반환하는 함수를 선언할 수 있지만 SQL 쿼리에서 이러한 함수를 사용할 수 없습니다.

의 답변은 Saish 님의 답변입니다.REGEXP_LIKE올바른 아이디어이지만 부동소수를 지원하지 않습니다.★★★★★★★★★★…

숫자 값 반환

SELECT  foo 
FROM    bar
WHERE   REGEXP_LIKE (foo,'^-?\d+(\.\d+)?$');

반환 값이 숫자가 아닙니다.

SELECT  foo 
FROM    bar
WHERE   NOT REGEXP_LIKE (foo,'^-?\d+(\.\d+)?$');

http://regexpal.com/에서 만족할 때까지 정규 표현 자체를 테스트할 수 있습니다(, 줄 바꿈 시 체크박스를 선택해야 합니다).

이는 Oracle에서 숫자 데이터가 포함되지 않은 행 찾기의 잠재적 복제입니다.다음 항목도 참조해 주세요.SQL에서 문자열이 숫자인지 확인하려면 어떻게 해야 합니까?

마이클 듀런트의 정수를 기반으로 한 솔루션이 있습니다.

SELECT foo
FROM bar
WHERE DECODE(TRIM(TRANSLATE(your_number,'0123456789',' ')), NULL, 'number','contains char') = 'number'

Adrian Carneiro는 소수점 및 기타에 적합한 솔루션을 게시했습니다.그러나 Justin Cave가 지적한 바와 같이 '123.45.23.234' 또는 '131+234'와 같은 문자열은 잘못 분류됩니다.

SELECT foo
FROM bar
WHERE DECODE(TRIM(TRANSLATE(your_number,'+-.0123456789',' ')), NULL, 'number','contains char') = 'number'

PL/SQL 또는 REGEXP_LIKE 를 사용하지 않는 솔루션이 필요한 경우는, 이 방법이 도움이 됩니다.

ORACLE(10g)에서는 다음과 같이 정규 표현 함수 'regexp_like'를 사용할 수 있습니다.

select case
       when regexp_like(myTable.id, '[[:digit:]]') then
        case
       when myTable.id > 0 then
        'Is a number greater than 0'
       else
        'Is a number less than or equal to 0'
     end else 'it is not a number' end as valuetype
from table myTable

용 i i사 i i i i i i i i i 。when others (하지 않기 에 "를 되돌리는 것) (SQL 부울 정수)를

create or replace function is_number(param in varchar2) return integer
 is
   ret number;
 begin
    ret := to_number(param);
    return 1; --true
 exception
    when invalid_number then return 0;
 end;

SQL 콜에서는 다음과 같은 것을 사용합니다.

select case when ( is_number(myTable.id)=1 and (myTable.id >'0') ) 
            then 'Is a number greater than 0' 
            else 'it is not a number or is not greater than 0' 
       end as valuetype  
  from table myTable

번호가 아닌 모든 항목을 찾기 위한 질문입니다.

Select myVarcharField
From myTable
where not REGEXP_LIKE(myVarcharField, '^(-)?\d+(\.\d+)?$', '')
and not REGEXP_LIKE(myVarcharField, '^(-)?\d+(\,\d+)?$', '');

제 분야에서는 유감스럽지만 10진수인 .와 .이 있습니다.그래서 그 점을 고려해야 합니다.그렇지 않으면 제한 중 하나만 있으면 됩니다.

열은 어떻게 정의됩니까?varchar 필드인 경우 번호가 아닙니다(또는 1로 저장됩니다).Oracle은 변환을 수행할 수 있지만(예: charField = 0인 일부 테이블에서 * 선택), 변환이 가능한 행만 반환합니다.이 또한 이상적인 상황에서의 퍼포먼스와는 거리가 멀다.

그래서 숫자 비교를 하고 이 열을 숫자로 처리하려면 숫자로 정의해야 합니다.

단, 다음과 같은 작업을 수행할 수 있습니다.

create or replace function myToNumber(i_val in varchar2) return number is
 v_num number;
begin
 begin
   select to_number(i_val) into v_num from dual;
 exception
   when invalid_number then
   return null;
 end;
 return v_num;
end;

또한 일반 to_number에 포함된 다른 매개 변수를 포함할 수도 있습니다.다음과 같이 사용:

select * from someTable where myToNumber(someCharField) > 0;

Oracle에서 잘못된 숫자로 간주하는 행은 반환되지 않습니다.

건배.

CREATE OR REPLACE FUNCTION is_number(N IN VARCHAR2) RETURN NUMBER IS
  BEGIN
    RETURN CASE regexp_like(N,'^[\+\-]?[0-9]*\.?[0-9]+$') WHEN TRUE THEN 1 ELSE 0 END;
END is_number;

45e4는 수치로 간주되지 않지만 언제든지 regex를 변경하여 그 반대로 할 수 있습니다.

@JustinCave - "when value_error" 대신 "when others"로 치환하는 것은 위의 접근방식을 적절히 개선한 것입니다.이 약간의 수정은 개념적으로는 동일하지만 l_num 변수에 대한 정의와 그에 따른 메모리 할당이 필요하지 않습니다.

function validNumber(vSomeValue IN varchar2)
     return varchar2 DETERMINISTIC PARALLEL_ENABLE
     is
begin
  return case when abs(vSomeValue) >= 0 then 'T' end;
exception
  when value_error then
    return 'F';
end;

또, 「위험성이 높은」REGEXP 어프로치를 사용해 Oracle 번호 포맷 로직을 에뮬레이트 하고 싶은 유저에게는, NLS_NUMERIC_CHARACTOR 및 NLS_TERRITORY를 고려해 주세요.

호출하는 is_number 함수를 생성하여 코드가 작동하도록 할 수 있습니다.

create or replace function is_number(param varchar2) return boolean
 as
   ret number;
 begin
    ret := to_number(param);
    return true;
 exception
    when others then return false;
 end;

편집: 저스틴의 답변을 따르세요.단순한 SQL 호출에 대한 자세한 내용을 잊어버렸습니다.

이 예를 사용할 수 있습니다.

SELECT NVL((SELECT 1 FROM  DUAL WHERE   REGEXP_LIKE (:VALOR,'^[[:digit:]]+$')),0) FROM DUAL;

regexp를 사용하여 9,8,7부터 시작하는 10자리 이동전화 번호에 대한 함수

create or replace FUNCTION VALIDATE_MOBILE_NUMBER
(   
   "MOBILE_NUMBER" IN varchar2
)
RETURN varchar2
IS
  v_result varchar2(10);

BEGIN
    CASE
    WHEN length(MOBILE_NUMBER) = 10 
    AND MOBILE_NUMBER IS NOT NULL
    AND REGEXP_LIKE(MOBILE_NUMBER, '^[0-9]+$')
    AND MOBILE_NUMBER Like '9%' OR MOBILE_NUMBER Like '8%' OR MOBILE_NUMBER Like '7%'
    then 
    v_result := 'valid';
    RETURN v_result;
      else 
      v_result := 'invalid';
       RETURN v_result;
       end case;
    END;

regexp 또는 함수 접근 방식은 일반 sql 조건보다 몇 배 느립니다.

따라서 적용 가능성이 제한적인 경험적 회피책 중 일부는 대규모 스캔에 적합합니다.

숫자 이외의 값에 알파벳 문자가 포함되어 있는 것을 확실히 알고 있는 경우의 해결책이 있습니다.

select case when upper(dummy)=lower(dummy) then '~numeric' else '~alpabetic' end from dual

또한 숫자가 아닌 경우에는 항상 문자가 표시됩니다.

select case when instr(dummy, 'X')>0 then '~alpabetic' else '~numeric' end from dual

숫자 대소문자가 항상 0인 경우:

select case when instr(dummy, '0')=0 then '~alpabetic' else '~numeric' end from dual

조건이 null이면 숫자입니다.

IF(rtrim(P_COD_LEGACY, '0123456789') IS NULL) THEN
                return 1;
          ELSE
                return 0;
          END IF;

다음은 간단한 방법입니다.

  • 트림에 의존하지 않음
  • REGEXP에 의존하지 않음
  • 10진수 및/또는 수천 개의 구분 기호("" 및 "")를 지정할 수 있습니다.
  • 8i와 같은 오래된 Oracle 버전에서 매우 잘 작동합니다(8.1.7.4.0에서 직접 테스트됨). 예, 제대로 읽으셨습니다.)
SELECT
    TEST_TABLE.*,

    CASE WHEN
        TRANSLATE(TEST_TABLE.TEST_COLUMN, 'a.,0123456789', 'a') IS NULL
    THEN 'Y'
    ELSE 'N'
    END
    AS IS_NUMERIC

FROM
    (
    -- DUMMY TEST TABLE
        (SELECT '1' AS TEST_COLUMN FROM DUAL) UNION
        (SELECT '1,000.00' AS TEST_COLUMN FROM DUAL) UNION
        (SELECT 'xyz1' AS TEST_COLUMN FROM DUAL) UNION
        (SELECT 'xyz 123' AS TEST_COLUMN FROM DUAL) UNION
        (SELECT '.,' AS TEST_COLUMN FROM DUAL)
    ) TEST_TABLE

결과:

TEST_COLUMN IS_NUMERIC
----------- ----------
.,          Y
1           Y
1,000.00    Y
xyz 123     N
xyz1        N

5 rows selected.

이 방법이 가장 강력한 방법은 아닐 수 있습니다. 예를 들어 "."는 수치로 잘못 식별됩니다.그러나 이 방법은 매우 단순하고 빠르며 처리해야 하는 실제 데이터 값에 따라 작업을 수행할 수 있습니다.

정수의 경우 다음과 같이 변환 작업을 단순화할 수 있습니다.

TRANSLATE(TEST_TABLE.TEST_COLUMN, 'a0123456789', 'a') IS NULL

구조

위에서부터 다음 점에 주의해 주세요.Translate함수의 구문은TRANSLATE(string, from_string, to_string)자, 이제.Translate함수가 받아들일 수 없음NULL처럼to_string논쟁.즉, 지정함으로써'a0123456789'처럼from_string그리고.'a'처럼to_string, 다음의 2가지 일이 발생합니다.

  • 성격a방치되어 있다.
  • 숫자0로.9에서 치환이 지정되어 있지 않기 때문에 아무것도 치환되지 않습니다.to_string.

사실상 숫자는 폐기됩니다.그 조작의 결과가 다음과 같은 경우NULL처음에는 숫자에 불과했다는 뜻이죠

언급URL : https://stackoverflow.com/questions/5082176/check-if-its-a-number-function-in-oracle

반응형