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
'programing' 카테고리의 다른 글
| 오류 TS1192: 모듈 'A.module'에 기본 내보내기가 없습니다. (0) | 2023.03.25 |
|---|---|
| @RunWith를 사용할 때와 @ExtendWith를 사용할 때 (0) | 2023.03.25 |
| Swift에서 HTML 엔티티를 디코딩하려면 어떻게 해야 하나요? (0) | 2023.03.25 |
| application.yml에서 루트 로깅 수준을 설정합니다. (0) | 2023.03.25 |
| angularjs에서와 같이 버튼을 사용하여 페이지를 탐색하는 간단한 방법이 있습니까? (0) | 2023.03.25 |