Oracle:
方法一:通過To_Number 函數異常來判斷,因為這個函數在轉換不成功的時候是報錯,所以只能用存儲過程包裝起來.
CREATE OR REPLACE FUNCTION Is_Number (
str_ VARCHAR2 ) RETURN VARCHAR2
IS
num_ NUMBER;
BEGIN
num_ := to_number(str_);
RETURN 'Y';
EXCEPTION
WHEN OTHERS THEN
RETURN 'N';
END Is_Number;
/
測試:
SQL> select Is_Number('12345') from dual;
IS_NUMBER('12345')
-------------------------
Y
SQL> select Is_Number('123.45') from dual;
IS_NUMBER('123.45')
--------------------------
Y
SQL> select Is_Number('123a') from dual;
IS_NUMBER('123A')
-----------------------
N
方法二:通過REGEXP_REPLACE/REGEXP_LIKE函數來實現
SQL> select nvl2(TRIM(REGEXP_replace('ss88','[0-9|+|-|.]','')),0,1) is_numerical from dual;
IS_NUMERICAL
------------
0
SQL> select nvl2(TRIM(REGEXP_REPLACE('2.88','[0-9|+|-|.]','')),0,1) is_numerical from dual;
IS_NUMERICAL
------------
1
SQL> SELECT CASE WHEN REGEXP_LIKE('1254','^[ +-.0-9]{4}$') then 1 else 0 end as is_numerical from dual;
IS_NUMERICAL
------------
1
方法三:通過 translate函數來實現,這個函數很強大,這里順便提下它的語法和其他用處.
TRANSLATE ( 'char' , 'from_string' , 'to_string' )
TRANSLATE returns char with all occurrences of each character in from_string replaced by its corresponding character in to_string.
Characters in char that are not in from_string are not replaced. The argument from_string can contain more characters than to_string.
In this case, the extra characters at the end of from_string have no corresponding characters in to_string. If these extra characters appear in char,then they are removed from the return value.You cannot use an empty string for to_string to remove all characters in from_string from the return value. Oracle interprets the empty string as null, and if this function has a null argument, then it returns null.
SELECT nvl2(translate('123','/1234567890','/'),'CHAR','NUMBER')
FROM dual ;
SQL> SELECT nvl2(translate('123','/1234567890','/'),'CHAR','NUMBER') TYPE
2 FROM dual;
TYPE
------------------------------
NUMBER
SQL>
SQL> SELECT nvl2(translate('123A','/1234567890','/'),'CHAR','NUMBER') TYPE
2 FROM dual;
TYPE
------------------------------
CHAR
在實際使用過程中,可以根據情況選用這兩種方法。第一種方法的好處是可以判斷帶小數的數字,而第二種方法只能判斷整數。
因為如果 translate 函數如果寫成 translate('123A','/1234567890.','/') 這種形式是會有問題的。
SQL> select Is_Number('123.45.6') TYPE from dual;
TYPE
--------------------------------------------------------------------------------
N
SQL> SELECT nvl2(translate('1234.5.6','/1234567890.','/'),'CHAR','NUMBER') TYPE FROM dual;
TYPE
------------------------------
NUMBER
解釋:
Translate中,每個from_string中的字符被to_string中相應的字符所代替。
select translate('acdd','cd','ef') from dual;→aeff
如果from_string比to_string長,那么from_string中多余的字符將被移除。
select translate('acdd','acd','ef') from dual;→ef (a由e 代替,c由f代替,d就被移除)
select translate('acdd','cda','ef') from dual;→eff(c由e 代替,d由f代替,a就被移除)
如果to_string為空,或者兩 者都為空,那么返回char也為空。所以to_string不能為空。
select translate('acdd','cd','') from dual;→ (空)
select translate('acdd','','') from dual;→(空)
實戰:
如何判斷一個字符串是否是數字?
解:先轉換:由於to_string不能為空,我們巧用#號代替
select translate('abc123','#1234567890.','#') from dual;→abc
from_string 中的#被to_string中的#代替,但char中又沒有#字符,所以通過這一步躲開了to_string必須不為空的規則。
然后后面的數字以及小數點 都轉換為空,於是原來的字符串中只留下abc三個字符。
轉換好后,用 nvl2判斷即可:
select nvl2(translate('abc123','#1234567890.','#'),'字符串','數字') from dual;→字符串
nvl2的作用就是,NVL2 (expr1, expr2, expr3) ->expr1不為NULL,返回expr2;為NULL,返回expr3.
從一串文本中提取數字:
select translate('用紙箱包200/箱','#'||REGEXP_replace('用紙箱包200PCS/箱','[0-9]',''),'#')from dual;
利用TRANSLATE實現關鍵字的過濾
有時候需要對一些關鍵詞語進行過濾,直接使用replace的話,可能由於這些關鍵詞語比較多而要嵌套使用,語句也不好寫,同時也浪費資源。
這種情況其實可以使用TRANSLATE和replace組合使用就能完全達到目的了。 比如要將“深圳”、“北京”等作為關鍵詞語,在顯示內容是要將這些詞語過濾掉不顯示:
- --首先使用TRANSLATE將關鍵詞語統一轉換成一個特殊的字符串,比如這里的X
- SQL> select TRANSLATE('上海北京天津重慶廣州深圳武漢','深圳北京','XXXX') from dual;
- TRANSLATE('上海北京天津重慶廣?
- ------------------------------
- 上海XX天津重慶廣州XX武漢
- --然后用replace將特殊的字符串替換掉。注意:不能用TRANSLATE直接將關鍵詞語直接轉換為''字符串
- SQL> select replace(TRANSLATE('上海北京天津重慶廣州深圳武漢','深圳北京','XXXX'),'X') from dual;
- REPLACE(TRANSLATE('上海北京天?
- ------------------------------
- 上海天津重慶廣州武漢
- SQL> --但是,用TRANSLATE是以一個字符為單位的,只要匹配到都會轉換。比如不管“北”和“京”是否連接在一起都會做轉換
- SQL> select TRANSLATE('上海京天津重慶北廣州深圳武漢','深圳北京','XXXX') from dual;
- TRANSLATE('上海京天津重慶北廣?
- ------------------------------
- 上海X天津重慶X廣州XX武漢
TRANSLATE(string,from,to)轉換的兩個注意
1、轉換源字串(from)在目的字串(to)中不存在對應,則轉換后被截除
2、轉換目的字串(to)不能為'',''在oracle中被視為空值,因此無法匹配而返回為null
另外,一個漢字作為一個字符還是兩個字符進行轉換與字符集的設置相關。
replace:字符串級別的代替
如:SELECT REPLACE('acdd','cd','ef') FROM dual; →aefd
translate:字符級別的代替
如:SELECT TRANSLATE('acdd','cd','ef') FROM dual; →aeff
REPLACE ( char , search_string [, replacement_string] )
REPLACE returns char with every occurrence of search_string replaced with replacement_string.
If replacement_string is omitted or null, then all occurrences of search_string are removed.
If search_string is null, then char is returned.
解 釋:repalce中,每個search_string都被replacement_string所代替。
select replace('acdd','cd','ef') from dual;→ aefd
如 果replacement_string為空或為NULL,那么所有的search_string都被移除。
select replace('acdd','cd','') from dual;→ad
如 果search_string為null,那么就返回原來的char。
select replace('acdd','','ef') from dual;→acdd
select replace('acdd','','') from dual; →acdd(也是兩者都為空的情況)
Both search_string and replacement_string, as well as char, can be any of the datatypes CHAR, VARCHAR2, NCHAR, NVARCHAR2, CLOB, or NCLOB.
The string returned is of VARCHAR2 datatype and is in the same character set as char.
This function provides functionality related to that provided by the TRANSLATE function.
TRANSLATE provides single-character, one-to-one substitution.
REPLACE lets you substitute one string for another as well as to remove character strings.
SQLSever:
ISNUMERIC
ISNUMERIC returns 1 when the input expression evaluates to a valid numeric data type; otherwise it returns 0. Valid numeric data types include the following:
int |
numeric |
bigint |
money |
smallint |
smallmoney |
tinyint |
float |
decimal |
real |
![]() |
---|
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL). |
SELECT ISNUMERIC('$') as is_numerical
is_numerical
--------------
1
SELECT ISNUMERIC('1.0E5') as is_numerical
is_numerical
-------
1
ISNUMERIC 校驗時認為科學計數法、貨幣符號均為合法,如果此類數據不加轉換
直接插入數據庫的float、decimal等字段中是會出異常。以下函數可用於校驗字符串是否為數字類型,僅允許輸入+、-、0-9、.字符.
--參數1:類型varchar 被校驗字符串 --參數2:類型int 整數位數長度 --參數3:類型int 小數位數長度,若為負數既不校驗小數位數長度 --返回值:類型int 返回"1"既檢驗正確,"0"既檢驗不通過(不是有效的數字類型或不符合規定的長度規范 if object_id('IS_NUMBER_NEW') is not null drop FUNCTION [dbo].[IS_NUMBER_NEW] ALTER FUNCTION [dbo].[IS_NUMBER_NEW] (@strVar VARCHAR(100),@i INT,@j INT) RETURNS INT AS BEGIN IF (ISNUMERIC(@strVar) = 0)--系統函數過濾絕大部分異常數據,但對於科學計數法等無法過濾 RETURN 0 ELSE BEGIN IF (@j = 0) BEGIN IF (PATINDEX('%[^0-9|+|-]%',@strVar) > 0) --整數校驗,只允許+、-、數字字符 RETURN 0 END ELSE BEGIN IF (PATINDEX('%[^0-9|.|+|-]%',@strVar) > 0) --帶小數校驗 RETURN 0 END SET @strVar = REPLACE(REPLACE(@strVar,'-',''),'+','')--最大值校驗 IF (CHARINDEX('.',@strVar) = 0) BEGIN IF (LEN(@strVar) > @i) RETURN 0 END ELSE BEGIN IF ((CHARINDEX('.',@strVar) - 1) > @i) RETURN 0 ELSE IF (@j >= 0) BEGIN IF (@j - DATALENGTH(SUBSTRING(@strVar,CHARINDEX('.',@strVar) + 1,99)) < 0) RETURN 0 END END END RETURN 1 END
PATINDEX
語法
PATINDEX ( '%pattern%' , expression )
參數
pattern 一個字符串。可以使用通配符,但 pattern 之前和之后必須有 % 字符(搜索第一個和最后一個字符時除外)。pattern 是短字符數據類型類別的表達式。
expression 一個表達式,通常為要在其中搜索指定模式的列,expression 為字符串數據類型類別。
返回類型 int
注釋
PATINDEX 對 text 數據類型很有用;除 IS NULL、IS NOT NULL 和 LIKE(這些是 Where 子句中對 text 類型有效的僅有的其它比較運算)外,PATINDEX 也可用於 Where 子句中。返回pattern字符串在表達式expression里第一次出現的位置,起始值從1開始算。pattern字符串在expression表達式里沒找就返回0,對所有有效的文本和字符串就是有效的數據類型。
描述一下此函數的具體用法:
找出Northwind.dbo.Categories表中Description字段中是包含單詞“Bread”或“bread”的所有記錄,那么選擇語句就可能是這樣:
Select Description from Northwind.dbo.Categories
Where patindex('%[b,B]read%',description) > 0
PATINDEX 中可以使用通配符來確定大寫和小寫的“b”
例二:
找出Northwind.dbo.Categories表中Description字段中是包含單詞“Bread”或“bread”,且第二子字母不是“e”的記錄。
select Description from Northwind.dbo.Categories
where patindex('%[b,B]read%',description) > 0 and patindex('_[^e]%',description) = 1
通過在條件語句中增加一個使用^通配符的PATINDEX函數,我們可以過濾掉“Dessert, candies, and sweet breads”這條記錄。上面的查詢結果只有一條記錄。
例三:
判斷字符串里不包含字母
select case when PATINDEX ('%[^0-9|+|-|.]%','ss88')=0 then 1 else 0 end as is_numerical;
PATINDEX與CHARINDEX
PATINDEX函數支持使用通配符,可以用在很多有變化的查找中。而CHARINDEX不可以。 根據你自己不同情況,這兩個函數對你在SQL Server中的字符串的搜索、控制、分析很有幫助。