특정 특수 문자에 대한 ISNUMERIC의 논리는 무엇입니까?


14

ISNUMERIC기능은 일부 예기치 않은 동작이 있습니다. MSDN 설명서는 다음과 같이 말합니다.

ISNUMERIC입력 표현식이 유효한 숫자 데이터 유형으로 평가되면 1을 리턴합니다. 유효한 숫자 데이터 유형에는 int, bigint, smallint, tinyint, decimal, numeric, money, smallmoney, float, real이 있습니다.

또한 각주도 있습니다.

ISNUMERIC더하기 (+), 빼기 (-)와 같이 숫자가 아닌 일부 문자 및 달러 기호 ($)와 같은 유효한 통화 기호에 대해서는 1을 반환합니다. 통화 기호의 전체 목록은 money 및 smallmoney (Transact-SQL)를 참조하십시오 .

따라서 +, -및 표시된 통화 기호는 숫자로 간주됩니다. 여태까지는 그런대로 잘됐다.

이제 이상한 부분입니다. 먼저 링크 된 기사의 일부 통화 기호는 다음을 포함하여 숫자 가 아닙니다 .

  • 유로 통화 기호, 16 진수 20A0 :
  • 나이라 부호, 16 진수 20A6 :
  • 리얼 사인, 16 진수 FDFC :

이것은 이상하고 왜 그런지 알지 못하는 것 같습니다. 이 버전 또는 환경이 종속적입니까?

그러나 상황이 더 이상해집니다. 내가 설명 할 수없는 몇 가지가 있습니다.

  • /숫자는 아니지만 \( 허?! )
  • REPLICATE(N'9', 308)숫자이지만 REPLICATE(N'9', 309)그렇지 않습니다

첫 번째이자 가장 기본적인 질문은 위의 경우를 설명하는 것 입니다. 더 중요한 것은 : 뒤에있는 논리는 무엇ISNUMERIC 입니까? 그래서 모든 경우를 직접 설명하고 예측할 수 있습니까?

다음은 물건을 재현하는 좋은 방법입니다.

DECLARE @tbl TABLE(txt NVARCHAR(1000));

INSERT INTO @tbl (txt) 
VALUES (N''), (N' '), (N'€'), (N'$'), (N'$$'), 
       (NCHAR(8356)), (NCHAR(8352)), (NCHAR(8358)), (NCHAR(65020)), 
       (N'+'), (N'-'), (N'/'), (N'\'), (N'_'), (N'e'), (N'1e'), (N'e1'), (N'1e1'), 
       (N'1'), (N'-1'), (N'+1'), (N'1+1'), (N''), (N'🄂'), (N'¹'), (N''), (N'½'), 
       (N'🎅'), (REPLICATE(N'9', 307)), (REPLICATE(N'9', 308)), (REPLICATE(N'9', 309)), 
       (REPLICATE(N'9', 310));

SELECT  UNICODE(LEFT(txt, 1)) AS FirstCharAsInt,
        LEN(txt) AS TxtLength,
        txt AS Txt,
        ISNUMERIC(txt) AS [ISNUMERIC]
FROM    @tbl;

로컬 Sql Server 2012 상자에서 이것을 실행하면 다음과 같은 결과가 나타납니다.

FirstCharAsInt   TxtLength   Txt        ISNUMERIC
---------------  ----------  ---------  ----------
NULL             0                      0
32               0                      0
8364             1           €          1
36               1           $          1
36               2           $$         0
8356             1           ₤          1
8352             1           ₠          0  --??
8358             1           ₦          0  --??
65020            1           ﷼‎          0  --??
43               1           +          1
45               1           -          1
47               1           /          0
92               1           \          1  --??
95               1           _          0
101              1           e          0
49               2           1e         0
101              2           e1         0
49               3           1e1        1
49               1           1          1
45               2           -1         1
43               2           +1         1
49               3           1+1        0
9352             1           ⒈         0
55356            2           🄂          0
185              1           ¹          0
9312             1           ①          0
189              1           ½          0
55356            2           🎅         0
57               307        /*...*/     1
57               308        /*...*/     1  --??
57               309        /*...*/     0  --??
57               310        /*...*/     0

나에게 옳지 않은 유일한 것은 0실제로 잘 캐스팅 된 값 중 5 개를 잘못보고한다는 것 money입니다. 다른 것들은 정확 해 보입니다. SQL FIDDLE
Martin Smith

비록 NCHAR(0) - NCHAR(65535)112 개의 불일치가 있습니다. ₁,₂,₃,4,5,6,7,8,9숫자 처럼 보이지만 성공적으로 캐스팅되지 않는 문자를 포함합니다 . 바이올린
마틴 스미스

답변:


13

자세한 동작은 ISNUMERIC문서화되지 않았으며 소스 코드 액세스 권한이없는 사람에게는 완전히 알려지지 않았을 것입니다. 즉, 해석은 유니 코드 분류 (숫자 여부)에 따라 달라질 수 있습니다. 마찬가지로, 이상한 사례는 이전 버전과의 호환성을 위해 보존 된 버그 일 수 있습니다. 예, 그 말이 미친 것 같지만 그런 일이 발생합니다.

SQL Server 2012를 사용하고 있으므로를 사용할 필요가 없습니다 ISNUMERIC. 문자열이 지정된 유형으로 변환 가능한지 확인하려면 대신 TRY_CONVERT또는 동의어 TRY_CAST를 사용하십시오 . 이들이 적절한 기능을 제공 TRY_PARSE하는 경우 CLR 통합을 통한 더 비싼 처리를 포함하기 때문에이 기능이 선호됩니다 .


2
그리고 아마도 소스 코드 액세스 권한을 가진 많은 사람들에게 완전히 알려지지 않았을 것입니다. :-) 두 번째 단락에서 다시 +1 할 수 있기를 바랍니다. ISNUMERIC ()은 무언가를 하나 이상의 숫자 유형으로 변환 할 수 있는지 여부를 결정하기 때문에 크게 쓸모가 없습니다. 단일의 특정 숫자 유형으로 변환 할 수 있다는 것을 아는 것이 훨씬 더 중요합니다.
Aaron Bertrand

1
@AaronBertrand 그 의도조차도 충족시키지 못하는 경우가 상당히 많은 것으로 보입니다.
Martin Smith

9

ASCII 백 슬래시 (코드 포인트 5C)는 일본어 버전의 Windows에서 사용되는 Shift-JIS 인코딩의 엔 부호 (¥) 및 한국어 EUC-KR의 원 부호 (₩)와 동일한 코드 포인트를 공유합니다. 따라서 이는 통화 기호 테마의 연속 일 가능성이 높습니다.


아 흥미로운 이론입니다. 그것은 또한 money캐스팅됩니다.
Martin Smith

@Jeroen- Wikipedia FWIW에 있습니다
Martin Smith

3
@Jeroen 나는 두렵지 않다. 일본어로 Windows 설치의 기존 코드 페이지를 전환하고 같은 경로를 얻을 C:¥Program Files¥Explorer.exe에서의
user47620
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.