2009-10-07 49 views
0

我在Oracle中比較了兩個數字。 010和10. 只要數字相等,它們是相等的;不過,我需要將它們作爲字符串進行比較。我試圖to_char,但它不起作用。在oracle中比較數字作爲字符串

是否有任何其他功能,可以讓我做數字值作爲字符串的精確比較?

------------爲了澄清大家的疑問---------------------

我有三列地址1地址2和地址3 我只想比較所有三個串聯的數字。因此,例如,如果值如下:
地址1 = 01公園大道
地址2 = 20金門
地址3 = NULL

然後我想在表中的數據進行比較,以查看是否有任何的地址級聯價值出來是0120

但是現在它是均衡120也與0120我不想要的。

數據被提取並連接,因此不存儲在某種類型的列中。我需要的只是確保這些數字是「完全」比較而不是數字。

請建議。

乾杯

+2

這些數字存儲在哪些列數據類型?你能寫一個腳本來顯示問題嗎? – 2009-10-07 06:06:36

回答

0

數字在數據庫中存儲爲varchars嗎?如果號碼存儲在整數變量那麼010將是相同的10

SELECT 010 FROM DUAL 

將返回10.這意味着,一旦你存儲前導零爲整任意數量的你失去前導零。你不能找回你失去的東西。

也許我錯誤地理解了你,你能改說你的問題嗎?

1

在這裏你並沒有真正的選擇 - 你可以比較字符串或數字。

The "strings": 
"10" 
"010" 
"0010" 
"00010" 

時轉換成整數的所有= 10

如果你開始一個整數10,你無法知道有多少前導零的它的「弦」的版本應該有辦法。所以,他們都存儲爲串,或將其作爲比較的數字 - 這意味着「10」 =「010」 =「0010」 = 10

0

你有一個字符串字段:

select '010' str from dual 

以下選擇將返回1行:

select * from (select '010' str from dual) where str=10 

下選擇將返回行:

select * from (select '010' str from dual) where str='10' 

所以,即使字段是如果喲字符串你只需在where子句中寫入=10 Oracle會將它們作爲數字進行比較。如果你寫='10' Oracle會將它們作爲字符串進行比較。

1

這是你在追求什麼?

設置一些示例數據:

create table address as 
select 
    '01 park avenue' address1, 
    '20 golden gate' address2, 
    '30 test' address3 
from 
    dual; 

insert into address 
select 
    '01 park avenue' address1, 
    '20 golden gate' address2, 
    null address3 
from 
    dual; 

insert into address 
select 
    '01 park avenue' address1, 
    '20 golden gate' address2, 
    null address3 
from 
    dual; 

commit; 

下面是將由串聯的串號訂購找到「重複」的查詢。我們使用地址級聯上的regexp_replace從地址中提取數字。

select 
    address1 || address2 || address3 address_concat, 
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]') 
      address_numbers_only 
from 
    address 
order by 
    address_numbers_only; 

如果你正在尋找一個特定的地址匹配 - 嘗試這樣的事:

select 
    * 
from 
    address 
where 
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]') = 
      regexp_replace(:v_address1 || 
        :v_address2 || 
        :v_address3, '[^[:digit:]]'); 

例如:

select 
    * 
from 
    address 
where 
    regexp_replace(address1 || address2 || address3, '[^[:digit:]]') = 
      regexp_replace('01 park avenue' || 
        '20 golden gate' || 
        null, '[^[:digit:]]'); 

-- returns... 

ADDRESS1  ADDRESS2  ADDRESS3 
01 park avenue 20 golden gate 
01 park avenue 20 golden gate 
+0

我認爲這給出了您所要求的內容,但APC在比較之前將分隔符包含在串聯中的方法是一種可行的方法。 – 2009-10-08 08:38:16

1

唯一的一個檢查正確的方法完全匹配將是

select whatever 
from addresses 
where address1 = '01' 
and address2 = '20' 
and address3 is null; 

(用綁定變量或其他列代替硬編碼值來品嚐)。

事實上,你忽略了這個明顯的解決方案,表明你有一些動機來比較連接字符串,你還沒有解釋。

串聯的匹配很麻煩,因爲你正在發現。它的工作原理是提供所有元素都被填充並且長度固定。一旦我們允許空值或可變長度值,我們註定會失敗。以下都不應該在元素的平等的基礎上匹配,但lo!通過級聯的魔力,他們做的事:

SQL> select * from dual 
    2 where 1||23 = 12||3 
    3/

D 
- 
X 

SQL> select * from dual 
    2 where 1||null||2 = 1||2||null 
    3/

D 
- 
X 

SQL> 
SQL> select * from dual 
    2 where 123||null||null = 1||2||3 
    3/

D 
- 
X 

SQL> 

此問題的解決方法是明確劃定在連接字符串中的元素。例如,如果我們將最後一個示例中的元素與代字符分開,我們將不再獲得匹配...

SQL> select * from dual 
    2 where 123||'~'||null||'~'||null = 1||'~'||2||'~'||3 
    3/

no rows selected 

SQL>