2012-10-17 8 views
20

एसक्यूएल सर्वर में System.Version स्टोर करने का सबसे अच्छा तरीका क्या है? हैसिस्टम के लिए डेटाटाइप एसक्यूएल सर्वर

1.0.0.0 
11.0.0.0 
12.0.0.0 
2.0.0.0 
+0

अच्छा प्रश्न –

+0

के लिए +1 आप किसी भी अन्य प्रासंगिक स्तंभ जो संस्करणों आदेश देने में मदद कर सकता है है? – V4Vendetta

+0

@ V4Vendetta नहीं, मेरे पास यह नहीं है –

उत्तर

8

आप एक varchar स्तंभ

आप इस

SELECT * 
FROM t_version 
ORDER BY CAST('/' + vid + '/' AS HIERARCHYID) 

एसक्यूएल बेला की तरह आदेश सकता है का उपयोग नहीं कर सकते:

मैं एएससी द्वारा varchar प्रकार, आदेश का परिणाम का उपयोग करते हैं है आज काम कर रहा है, अन्यथा मैं एक डेमो दिखा सकता था

कृपया इसे परीक्षण के लिए चलाएं ing

SELECT * FROM 
(VALUES 
     ('1.0.0.0'), 
     ('11.0.0.0'), 
     ('12.0.0.0'), 
     ('2.0.0.0')) AS vid (vid) 
ORDER BY CAST('/' + vid + '/' AS HIERARCHYID) 
+0

युक्ति: आप प्रदर्शन उत्तरों के लिए 'यूनियन ऑल' के बजाय 'VALUES' का अधिक आसानी से उपयोग कर सकते हैं:' चुनें * से (मूल्य ('1.0.0.0'), ('11.00.0.0) ') ...) एएस vid (vid) द्वारा आदेश ... ' – hvd

+0

@hvd: इसके लिए धन्यवाद, यह क्लीनर दिखता है .. मैंने अपना जवाब –

+1

@hvd अपडेट किया है जब तक कि सवाल को टैग नहीं किया जाता है जब तक कि प्रश्न' sql-server -2008', या 2012 – RichardTheKiwi

7

बस एक सामान्य varchar, जो PARSENAME का उपयोग कर स्ट्रिंग और 4 अलग-अलग कॉलम द्वारा आदेश विभाजित करने के लिए 4 भागों से ऊपर संस्करणों के लिए अच्छा है के रूप में संग्रहीत।

अर्थात

ORDER BY PARSENAME(version,4), 
     PARSENAME(version,3), 
     PARSENAME(version,2), 
     PARSENAME(version,1) 
+1

+1 - बहुत ही सुरुचिपूर्ण और मेरे लिए एक नया! –

0

मिश्रित लंबाई संस्करणों (जैसे '1.2' बनाम '1.2.3.4') के बीच के आदेश का समर्थन करने के लिए, एक दशमलव करने के लिए एक मानचित्रण (इनलाइन तालिका महत्वपूर्ण कार्यों के रूप में) का प्रदर्शन किया जा सकता है।

create function Common.ufn_OrderableVersion(@pVersion nvarchar(100)) 
returns table 
as 
/*--------------------------------------------------------------------------------------------------------------------- 
    Purpose: Provide a mapping from Versions of the form 'a.b.c.d', 'a.b.c, 'a.b', 'a', null to 
       an orderable decimal(25, 0) 

       Since Parsename() doesn't apply easily to mixed length comparisions (1.2 vs 1.2.3.4) 

Test Cases: 
       select * from Common.ufn_OrderableVersion(null);  -- null 
       select * from Common.ufn_OrderableVersion('0');  -- 1000000000000000000000000 
       select * from Common.ufn_OrderableVersion('1');  -- 1000001000000000000000000 
       select * from Common.ufn_OrderableVersion('1.2.3.4'); -- 1000001000002000003000004 

       select Version 
       from 
        (
         select '1.3.5.3' as Version 
         union all 
         select '1.2.5.3' as Version 
         union all 
         select '1.1.5.3' as Version 
         union all 
         select '1.3.5.2' as Version 
         union all 
         select null as Version 
         union all      
         select '' as Version 
         union all 
         select '2' as Version 
         union all 
         select '1.2' as Version 
         union all 
         select '1' as Version      
        ) v 
       order by (select Value from Common.ufn_OrderableVersion(Version)) 

    Modified By    Description 
    ---------- -------------- --------------------------------------------------------------------------------------- 
    2015.08.24 crokusek  Initial Version 
    ---------------------------------------------------------------------------------------------------------------------*/ 
return   
    -- 25 = 1 + VersionPositions * MaxDigitsPerSegment 
    select convert(decimal(25,0), '1' + 
      stuff((select format(Value, '000000') 
        from 
         (
          select convert(int, Value) as Value, RowNumber 
           -- Support empty string and partial versions. Null maps to null 
          from Common.ufn_SplitUsingXml(@pVersion + '.0.0.0.0', '.') -- pad right 
          where RowNumber <= 4 -- trim right 
         ) as v 
        order by RowNumber 
        for xml path ('') 
       ), 1, 0, '') 
      ) as Value 
go 

निर्भरता:

create function Common.ufn_SplitUsingXml 
(
    @pList  nvarchar(max), 
    @pDelimiter nvarchar(255) 
) 
returns table 
as 
/*--------------------------------------------------------------------------------------------------------------------- 
    Purpose: Split an Identifier using XML as an inline table valued function. 
       Using the SQL Server CLR (C#) capability would be the most efficient way to support this. 

    Warnings: Will not work if the input contains special XML characters like '<', '>' or '&'. 
       Caller must add "option (maxrecursion 0)" for lists greater than 100 (it can't be added within the ufn)     

    Modified By    Description 
    ---------- -------------- --------------------------------------------------------------------------------------- 
    2015.08.24 inet   http://sqlperformance.com/2012/07/t-sql-queries/split-strings 
    ---------------------------------------------------------------------------------------------------------------------*/ 
return 
( 
    select Value = y.i.value('(./text())[1]', 'nvarchar(4000)'), 
     row_number() over (order by (select null)) as RowNumber 
    from 
    ( 
    select x = convert(XML, '<i>' 
     + replace(@pList, @pDelimiter, '</i><i>') 
     + '</i>').query('.') 
) AS a cross apply x.nodes('i') AS y(i) 
    -- option (maxrecursion 0) must be added by caller for lists greater than 100 
); 
go 

तुलना:

alter function Common.ufn_CompareVersions 
(
    @pVersionA nvarchar(100), 
    @pVersionB nvarchar(100) 
) 
returns table 
as 
/*--------------------------------------------------------------------------------------------------------------------- 
    Purpose: Compare Version of the form 'A.B.C.D'. 
       Comparing versions of different lengths is also supported 'A.B'. 

Test Cases: 
       select Result from Common.ufn_CompareVersions('1', null) -- 1 
       select Result from Common.ufn_CompareVersions(null, '1') -- -1 
       select Result from Common.ufn_CompareVersions('1', '1') -- 0 
       select Result from Common.ufn_CompareVersions('1', '2') -- -1 
       select Result from Common.ufn_CompareVersions('2', '1') -- 1 
       select Result from Common.ufn_CompareVersions('1', '1.2') -- -1 
       select Result from Common.ufn_CompareVersions('1.2', '1') -- 1 
       select Result from Common.ufn_CompareVersions('1.2.3.4', '1.2.3.4') -- 0 
       select Result from Common.ufn_CompareVersions('1.2.3', '1.2.3.4') -- -1 
       select Result from Common.ufn_CompareVersions('1.2.3.4', '1.2.3') -- 1 
       select Result from Common.ufn_CompareVersions('1.9.3.4', '1.2.3.4') -- 1 
       select Result from Common.ufn_CompareVersions('1.2.3.4', '1.9.3.4') -- -1 
       select Result from Common.ufn_CompareVersions('1.002', '1.2') -- 0 
       select Result from Common.ufn_CompareVersions('1.2', '1.2.0') -- 0 

    Modified By   Description 
    ---------- ----------- ------------------------------------------------------------------------------------------ 
    2015.08.24 crokusek  Initial Version 
    ---------------------------------------------------------------------------------------------------------------------*/ 
return  
    with Compares as 
    (
     select (select IsNull(Value, 0) from Common.ufn_OrderableVersion(@pVersionA)) as A, 
      (select IsNull(Value, 0) from Common.ufn_OrderableVersion(@pVersionB)) as B 
    ) 
    select case when A > B then 1 
       when A < B then -1 
       else 0 
      end as Result 
     from Compares 
go 
संबंधित मुद्दे