2011-11-24 67 views
1

我有一個領域,包含說明和美元金額的混合。有了TSQL,我想提取這些美元金額,然後將它們插入到一個新的記錄領域。從現有的sql數據中提取美元金額?

- 更新 -

一些數據樣本可能是:

Used knife set for sale $200.00 or best offer. 
$4,500 Persian rug for sale. 
Today only, $100 rebate. 
Five items for sale: $20 Motorola phone car charger, $150 PS2, $50.00 3 foot high shelf. 

在組上面我想的只是抓住了美元的數字中第一次出現......這是最簡單的。

我不想從原始文本中刪除金額,只是獲取它們的值,並將它們添加到新字段。

金額可能/不能包含小數和逗號。

我確定PATINDEX不會削減它,我不需要一個非常RegEx函數來完成此操作。

然而,看着OLE正則表達式查找(執行)功能here,似乎是最強大的,試圖用我得到SSMS以下錯誤消息的功能然而,當:

SQL Server阻止訪問組件 'Ole Automation Procedures'的過程'sys.sp_OACreate',因爲此組件被關閉爲此服務器的安全配置的 部分。系統 管理員可以使用sp_configure啓用 中的'Ole Automation Procedures'。有關啓用「Ole 自動化過程」的更多信息,請參閱SQL Server的聯機叢書中的「表面區域配置」。

我不想去改變我的服務器設置只是爲了這個功能。我有另一個正則表達式函數,沒有改變就可以正常工作。

我無法想象這是複雜的只是提取美元金額。任何更簡單的方法?

謝謝。

+1

您能否提供一個列內容的樣本,以及您希望從中提取的內容? –

+0

比使用OLE更好地使用CLR regexp實現; http://www.codeproject.com/KB/string/SqlRegEx.aspx如果t-sql不符合任務 –

+0

亞歷克斯是正確的。使用C#編寫自己的字符串提取函數可能會更快,然後使用CLR將其導入到SQL代碼中。在服務器上啓用CLR不應導致任何不良副作用。 – deutschZuid

回答

2
CREATE FUNCTION dbo.fnGetAmounts(@str nvarchar(max)) 
    RETURNS TABLE 
    AS 
    RETURN 
    (
    -- generate all possible starting positions (1 to len(@str)) 
    WITH StartingPositions AS 
    (
     SELECT 1 AS Position 
     UNION ALL 
     SELECT Position+1 
     FROM StartingPositions 
     WHERE Position <= LEN(@str) 
    ) 
    -- generate possible lengths 
    , Lengths AS 
    (
     SELECT 1 AS [Length] 
     UNION ALL 
     SELECT [Length]+1 
     FROM Lengths 
     WHERE [Length] <= 15 
    ) 
    -- a Cartesian product between StartingPositions and Lengths 
    -- if the substring is numeric then get it 
    ,PossibleCombinations AS 
    (

     SELECT CASE     
       WHEN ISNUMERIC(substring(@str,sp.Position,l.Length)) = 1 
        THEN substring(@str,sp.Position,l.Length)   
       ELSE null END as Number 
       ,sp.Position 
       ,l.Length 
     FROM StartingPositions sp, Lengths l   
     WHERE sp.Position <= LEN(@str)    
    ) 
-- get only the numbers that start with Dollar Sign, 
-- group by starting position and take the maximum value 
-- (ie, from $, $2, $20, $200 etc) 
    SELECT MAX(convert(money, Number)) as Amount 
    FROM PossibleCombinations 
    WHERE Number like '$%' 
    GROUP BY Position 
    ) 

    GO 

    declare @str nvarchar(max) = 'Used knife set for sale $200.00 or best offer. 
    $4,500 Persian rug for sale. 
    Today only, $100 rebate. 
    Five items for sale: $20 Motorola phone car charger, $150 PS2, $50.00 3 foot high shelf.' 

    SELECT * 
    FROM dbo.fnGetAmounts(@str) 
    OPTION(MAXRECURSION 32767) -- max recursion option is required in the select that uses this function 
+0

這很酷。對於我一直在尋找的東西,我有點矯枉過正,但太好了!我將這個函數添加到我的數據庫中以供將來使用。謝謝! – ElHaix

+0

歡迎,我不推薦它。一個CLR函數可以更好地處理大集合/文本 –

相關問題