2012-11-09 24 views
2

可能重複:
How to compare software versions using SQL Server?如何比較保存版本號如.NET System.Version類的SQL字符串?

我是一個完整的,完全新的到SQL,但今天我發現在這裏工作的SQL查詢,這是非常重要的一個錯誤。所以,我可以利用一些幫助:

鑑於代表產品版本

'15 SQL字符串.0.0.0'

是有排序或比較相似,如何.NET類,串一個萬無一失的方法System.Version比較實例嗎?因此,考慮到這樣一種假設的結構,或者功能或者曾經的,我預計'15.5.568'將會大於'15.0.0.0'。

謝謝

回答

5

一個例子假設SQL Server和一個已知的最大零件數量,這裏是用戶定義的功能,其功能與parsename相同,但適用於任意數量的零件:

Create Function dbo.VersionNthPart(@version as nvarchar(max), @part as int) returns int as 
Begin 

    Declare 
    @ret as int = null, 
    @start as int = 1, 
    @end as int = 0, 
    @partsFound as int = 0 

    if @version is not null 
    Begin 
    Set @ret = 0 
    while @partsFound < @part 
    Begin 
     Set @end = charindex('.', @version, @start) 
     If @end = 0 
     Set @partsFound = @part -- bail early 
     else 
     Begin 
     Set @partsFound = @partsFound + 1 
     If @partsFound = @part 
      Set @ret = Convert(int, substring(@version, @start, @end - @start)) 
     Else 
      Set @start = @end + 1 
     End 
    End 
    End 
    return @ret 
End 

實例應用:

With 
    tmp 
As (
    Select '1.0.0.5' As Version 
    Union All Select '1.5.0.06' 
    Union All Select '1.0.0.06' 
    Union All Select '2.0.0.0' 
    Union All Select '2.0.1.1' 
    Union All Select '15.5.568' 
    Union All Select '15.0.0.0' 
    Union All Select '15.15.1323.22' 
    Union All Select '15.15.622.55' 
) 

Select 
    * 
From 
    tmp 
Order By 
    dbo.VersionNthPart(Version, 1), 
    dbo.VersionNthPart(Version, 2), 
    dbo.VersionNthPart(Version, 3), 
    dbo.VersionNthPart(Version, 4) 

http://sqlfiddle.com/#!3/e942b/3

+0

雖然我不理解函數部分,但示例用法看起來很簡單。非常感謝! –

2

如果你有不超過三個小數點,那麼你可以使用parsename。以下將兩個版本號修正爲具有4個字符的值,所以字符串比較owrks。你的例子是「0015.0000.0000.0000.0000」。

select (case when (right('0000'+coalesce(parsename(v1, 4), '', 4)) + 
        right('0000'+coalesce(parsename(v1, 3), '', 4)) + 
        right('0000'+coalesce(parsename(v1, 2), '', 4)) + 
        right('0000'+coalesce(parsename(v1, 1), '', 4)) 
       ) < 
        (right('0000'+coalesce(parsename(v2, 4), '', 4)) + 
        right('0000'+coalesce(parsename(v2, 3), '', 4)) + 
        right('0000'+coalesce(parsename(v2, 2), '', 4)) + 
        right('0000'+coalesce(parsename(v2, 1), '', 4)) 
       ) 
      then -1 
      when v1 = v2 
      then 0 
      else 1 
     end) as Comparison 

請注意,parsename()僅適用於最多四個部分的名稱。

如果你只是想進行排序,那麼下面的工作:

order by (right('0000'+coalesce(parsename(v1, 4), '', 4)) + 
      right('0000'+coalesce(parsename(v1, 3), '', 4)) + 
      right('0000'+coalesce(parsename(v1, 2), '', 4)) + 
      right('0000'+coalesce(parsename(v1, 1), '', 4)) 
     ) 
+0

不知道如何使用這一個... –

+0

的'case'表達時版本V1小於V2版返回0值-1,當它們相等時,以及當版本v1更大時爲1。我的理解是,您正在尋找比較版本的方法。 –

+0

'右( '0000' +聚結(PARSENAME(V1,4),4), '')' 應該是 '右( '0000' +聚結(PARSENAME(V1,4), '') ,4)' – jo0ls

5

只是增加了什麼@Gordon建議,在這裏與PARSENAME

; WITH tmp 
AS 
(
    SELECT '1.0.0.5' AS Version 
    UNION ALL SELECT '1.5.0.06' 
    UNION ALL SELECT '1.0.0.06' 
    UNION ALL SELECT '2.0.0.0' 
    UNION ALL SELECT '2.0.1.1' 
    UNION ALL SELECT '15.15.1323.22' 
    UNION ALL SELECT '15.15.622.55' 
) 
SELECT * 
FROM 
(
    SELECT CAST(PARSENAME(Version, 4) AS INT) AS col1 
     , CAST(PARSENAME(Version, 3) AS INT) AS col2 
     , CAST(PARSENAME(Version, 2) AS INT) AS col3 
     , CAST(PARSENAME(Version, 1) AS INT) AS col4 
    FROM tmp 
) t0 
ORDER BY col1, col2, col3, col4 
+0

非常感謝! –

+0

哇,聰明,並通過var我在網上找到最簡單的方法。道具! –