2010-02-05 52 views
3

我有一種情況,即傳入的數據值可能有或沒有前導零。我需要將它匹配到SQL Server表中的字段/行。 SQL Server數據庫中的字段值可能也可能不具有前導零。在SQL Server表中匹配具有可變數量前導零的字段

所以,我可能有:

  • 傳入= 5042800138
    和分貝值可以是任何5042800138,05042800138,005042800138,0005042800138

  • 或傳入的可能是005042800138
    和db中的值可以是5042800138,05042800138,005042800138,0005042800138中的任何一個

我想出瞭解決的辦法是去掉前導零(總是)上輸入數據,並使用SQL像下面的例子:

-- this simulates the incoming value to check 
-- i strip out the leading zeroes. 
declare @tryUPC as varchar(40) 
set @tryUPC = '5042800138' 

-- try to find it in the database and ignore leading zeroes 
select prod_uid, prod_partno, prod_upc 
from products as p 
where (prod_upc = @tryUPC) or 
    (
    len(prod_upc) > len(@tryUPC) 
    and right(prod_upc, len(@tryUPC)) = @tryUPC 
    and stuff(prod_upc, 1, len(prod_upc) - len(@tryUPC), '0') = prod_upc 
    ) 

這似乎是工作。我的問題是,我錯過了什麼? SQL Server是否有更好的方式來處理這個問題?我使用SQL Server 2005的

TIA,

+0

看到我的編輯,它顯示了你如何使用索引 – 2010-02-05 19:13:51

回答

2

如果你不能改變現有的數據剝去前導零/轉換爲INT,它可能會更快,只是做一些事情,像這樣:

WHERE prod_upc IN (@tryUPC, '0' + @tryUPC, '00' + @tryUPC, '000' + @tryUPC [...]) 

這就像我的腳一樣優雅,但它會更加靜態,並且(可能)更有可能獲得任何相關索引。

這是假設您有多少前導零有一個有限的限制,介意。將數據轉換爲INT(或添加新的INT列並在插入時計算它)可能是解決此問題的最佳解決方案。

+0

我想這可能會更好。我必須看看允許的前導零數。爲了使它處理如此之多的零可能是沒有必要的。謝謝 – 2010-02-05 19:10:45

+0

只要數據不分段,我肯定會推薦這個(分段含義)。或者,你可以填充所有的特定數量的零(123-> 00123,0123-> 00123,00123-> 00123等)。如上所述,密鑰是你正在比較的兩者之間的一致性。 – KSimons 2010-02-05 19:17:28

0

1)更新所有的現有數據不具有任何前導零,可能使用BIGINT數據類型
2)總是從剝離前導零保存和搜索前的輸入
3)再也不用擔心引導零,而且你實際上可以使用索引!

編輯 後OP的評論:

就不是很好,但它不是現實。我想我應該提到這是一個傳統的應用程序。 upc代碼可以輸入到一堆不同的地方。改變數據類型將需要大規模的重構。此外,有時需要零 - 數據庫有一個很好的理由。 - 唐·迪金森

你可以使用一個持久的計算列,其中你REVERSE()列,然後索引它。然後,您可以查詢:

WHERE Column1Reverse Like REVERSE('1234567')+'%' --can use the persistent computed column's index 

添加一個持久化計算列(即反轉字符串)和指數就可以了,使用此代碼:

ALTER TABLE YourTable ADD ReversedYourString反向(YourString)堅持

CREATE NONCLUSTERED INDEX IX_YourTable_ReversedYourString 
ON YourTable (ReversedYourString) 
+0

+1 - 擊敗了我。我所建議的一切也是爲了將數據轉化爲理想/最佳格式來查詢 – AdaTheDev 2010-02-05 18:37:10

+0

@AdaTheDev忘了一個:......將數據轉化爲理想/最優/ **一致**格式...... – 2010-02-05 18:39:38

+0

@KM - 是的!一致性是冠軍:) – AdaTheDev 2010-02-05 18:48:52

4

只是另一個傾向(糾正數據將是最好的,但接受的答案也是一個體面的解決方法):添加一個持久的索引計算列「actualUPC」,是一個字符類型,用正確數量的前導零計算。例如:

如果「真實」代碼被認爲是12位數字,使象

right('000000000000' + originalColumn, 12) 

這樣實際上對輸入數據進行校正計算列,然後索引正確,並且可以與索引進行搜索。

當您查詢時,還會填充輸入以匹配,作爲查詢中的常量。

檢查對索引計算列的限制,但是在太瘋狂之前。這樣的BTW代碼(郵政編碼,序列號,ssn's等)總是應該以文本數據存儲,前導零,而不能作爲整數或數字類型存儲。從一個在郵政編碼01033長大的男人身上拿走它。