복붙노트

[SQL] 어떻게 SQL Server를 사용하여 소프트웨어 버전을 비교?

SQL

어떻게 SQL Server를 사용하여 소프트웨어 버전을 비교?

5.12 5.8 소프트웨어 버전을 비교하려고 할 때, 버전 5.12 그러나 수학적으로 5.12 5.8 이하이며, 새로운이다. 어떻게 두 가지 버전이 최신 버전 반환 'Y'를 수 있도록 비교까요?

SELECT CASE WHEN 5.12 > 5.8 THEN 'Y' ELSE 'N' END

가능한 해결책

해결법

  1. ==============================

    1.

    declare @v1 varchar(100) = '5.12'
    declare @v2 varchar(100) = '5.8'
    
    select 
        case 
        when CONVERT(int, LEFT(@v1, CHARINDEX('.', @v1)-1)) < CONVERT(int, LEFT(@v2, CHARINDEX('.', @v2)-1)) then 'v2 is newer'
        when CONVERT(int, LEFT(@v1, CHARINDEX('.', @v1)-1)) > CONVERT(int, LEFT(@v2, CHARINDEX('.', @v2)-1)) then 'v1 is newer'
        when CONVERT(int, substring(@v1, CHARINDEX('.', @v1)+1, LEN(@v1))) < CONVERT(int, substring(@v2, CHARINDEX('.', @v2)+1, LEN(@v1))) then 'v2 is newer'
        when CONVERT(int, substring(@v1, CHARINDEX('.', @v1)+1, LEN(@v1))) > CONVERT(int, substring(@v2, CHARINDEX('.', @v2)+1, LEN(@v1))) then 'v1 is newer'
        else 'same!'
    
        end
    
  2. ==============================

    2.나는 SQL의 CLR 기능을 작성하는 것이 좋습니다 :

    나는 SQL의 CLR 기능을 작성하는 것이 좋습니다 :

    public partial class UserDefinedFunctions
    {
        [SqlFunction(Name = "CompareVersion")] 
        public static bool CompareVersion(SqlString x, SqlString y)
        {
            return Version.Parse(x) > Version.Parse(y);
        }
    }
    

    노트:

  3. ==============================

    3.여기에 중복 질문에서 아주 좋은 해결책이 있었다 : 어떻게 .NET System.Version 클래스와 같은 홀드 버전 번호가 SQL 문자열을 비교?

    여기에 중복 질문에서 아주 좋은 해결책이 있었다 : 어떻게 .NET System.Version 클래스와 같은 홀드 버전 번호가 SQL 문자열을 비교?

    잠시 동안 쿼리와 함께 연주 후, 나는 4 개 이상의 부품 (버전 번호가 1.2.3.4 인 경우 말, 항상 0으로 마지막을 치료하는 것)이있을 때 마지막 부분을 비교할 수 없음을 알게 . 나는 문제뿐만 아니라 두 버전 번호를 비교하는 또 다른 기능 해낸 것을 해결했습니다.

    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,
        @terminate as bit = 0
    
      if @version is not null
      Begin
        Set @ret = 0
        while @partsFound < @part
        Begin
          Set @end = charindex('.', @version, @start)
          If @end = 0 -- did not find the dot. Either it was last part or the part was missing.
          begin
            if @part - @partsFound > 1 -- also this isn't the last part so it must bail early.
            begin
                set @terminate = 1
            end
            Set @partsFound = @part
            SET @end = len(@version) + 1; -- get the full length so that it can grab the whole of the final part.
          end
          else
          begin
            SET @partsFound = @partsFound + 1
          end
          If @partsFound = @part and @terminate = 0
          begin
                Set @ret = Convert(int, substring(@version, @start, @end - @start))
          end
          Else
          begin
                Set @start = @end + 1
          end
        End
      End
      return @ret
    End
    GO
    
    CREATE FUNCTION [dbo].[CompareVersionNumbers]
    (
        @Source nvarchar(max),
        @Target nvarchar(max),
        @Parts int = 4
    )
    RETURNS INT
    AS
    BEGIN
    /*
    -1 : target has higher version number (later version)
    0 : same
    1 : source has higher version number (later version)
    */ 
        DECLARE @ReturnValue as int = 0;
        DECLARE @PartIndex as int = 1;
        DECLARE @SourcePartValue as int = 0;
        DECLARE @TargetPartValue as int = 0;
        WHILE (@PartIndex <= @Parts AND @ReturnValue = 0)
        BEGIN
            SET @SourcePartValue = [dbo].[VersionNthPart](@Source, @PartIndex);
            SET @TargetPartValue = [dbo].[VersionNthPart](@Target, @PartIndex);
            IF @SourcePartValue > @TargetPartValue
                SET @ReturnValue = 1
            ELSE IF @SourcePartValue < @TargetPartValue
                SET @ReturnValue = -1
            SET @PartIndex = @PartIndex + 1;
        END
        RETURN @ReturnValue
    END
    

    사용 / 테스트 케이스 :

    declare @Source as nvarchar(100) = '4.9.21.018'
    declare @Target as nvarchar(100) = '4.9.21.180'
    SELECT [dbo].[CompareVersionNumbers](@Source, @Target, DEFAULT) -- default version parts are 4
    
    SET @Source = '1.0.4.1'
    SET @Target = '1.0.1.8'
    SELECT [dbo].[CompareVersionNumbers](@Source, @Target, 4) -- typing out # of version parts also works
    
    SELECT [dbo].[CompareVersionNumbers](@Source, @Target, 2) -- comparing only 2 parts should be the same
    
    SET @Target = '1.0.4.1.5'
    SELECT [dbo].[CompareVersionNumbers](@Source, @Target, 4) -- only comparing up to parts 4 so they are the same
    SELECT [dbo].[CompareVersionNumbers](@Source, @Target, 5) -- now comparing 5th part which should indicate that the target has higher version number
    
  4. ==============================

    4.의미 론적 버전을 기반으로 필터 SQL 행하려고 할 때 나는이 발생했습니다. 내가 구성 행이 의미 론적 버전 번호로 태그 한 후 우리의 소프트웨어의 실행 버전과 호환 행을 선택 저장하고 싶어한다는 점에서 내 솔루션은 조금 달랐다.

    의미 론적 버전을 기반으로 필터 SQL 행하려고 할 때 나는이 발생했습니다. 내가 구성 행이 의미 론적 버전 번호로 태그 한 후 우리의 소프트웨어의 실행 버전과 호환 행을 선택 저장하고 싶어한다는 점에서 내 솔루션은 조금 달랐다.

    가정 :

    예를 들면 :

    MSSQL UDF는 다음과 같습니다

    CREATE FUNCTION [dbo].[SemanticVersion] (
        @Version nvarchar(50)
    )
    RETURNS nvarchar(255)
    
    AS
    BEGIN
    
        DECLARE @hyphen int = CHARINDEX('-', @version)
        SET @Version = REPLACE(@Version, '*', ' ')
        DECLARE 
            @left nvarchar(50) = CASE @hyphen WHEN 0 THEN @version ELSE SUBSTRING(@version, 1, @hyphen-1) END,
            @right nvarchar(50) = CASE @hyphen WHEN 0 THEN NULL ELSE SUBSTRING(@version, @hyphen+1, 50) END,
            @normalized nvarchar(255) = '',
            @buffer int = 8
    
        WHILE CHARINDEX('.', @left) > 0 BEGIN
            SET @normalized = @normalized + CASE ISNUMERIC(LEFT(@left, CHARINDEX('.', @left)-1))
                WHEN 0 THEN LEFT(@left, CHARINDEX('.', @left)-1)
                WHEN 1 THEN REPLACE(STR(LEFT(@left, CHARINDEX('.', @left)-1), @buffer), SPACE(1), '0')
            END  + '.'
            SET @left = SUBSTRING(@left, CHARINDEX('.', @left)+1, 50)
        END
        SET @normalized = @normalized + CASE ISNUMERIC(@left)
            WHEN 0 THEN @left
            WHEN 1 THEN REPLACE(STR(@left, @buffer), SPACE(1), '0')
        END
    
        SET @normalized = @normalized + '-'
        IF (@right IS NOT NULL) BEGIN
            WHILE CHARINDEX('.', @right) > 0 BEGIN
                SET @normalized = @normalized + CASE ISNUMERIC(LEFT(@right, CHARINDEX('.', @right)-1))
                    WHEN 0 THEN LEFT(@right, CHARINDEX('.', @right)-1)
                    WHEN 1 THEN REPLACE(STR(LEFT(@right, CHARINDEX('.', @right)-1), @buffer), SPACE(1), '0')
                END  + '.'
                SET @right = SUBSTRING(@right, CHARINDEX('.', @right)+1, 50)
            END
            SET @normalized = @normalized + CASE ISNUMERIC(@right)
                WHEN 0 THEN @right
                WHEN 1 THEN REPLACE(STR(@right, @buffer), SPACE(1), '0')
            END
        END ELSE 
            SET @normalized = @normalized + 'zzzzzzzzzz'
    
        RETURN @normalized
    
    END
    

    SQL 시험은 다음과 같습니다 :

    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-alpha') < dbo.SemanticVersion('1.0.0-alpha.1') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-alpha.1') < dbo.SemanticVersion('1.0.0-alpha.beta') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-alpha.beta') < dbo.SemanticVersion('1.0.0-beta') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-beta') < dbo.SemanticVersion('1.0.0-beta.2') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-beta.2') < dbo.SemanticVersion('1.0.0-beta.11') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-beta.11') < dbo.SemanticVersion('1.0.0-rc.1') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-rc.1') < dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    
    
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-*') <= dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.*') <= dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.*') <= dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('*') <= dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    
    SELECT CASE WHEN dbo.SemanticVersion('1.0.0-*') <= dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.1-*') > dbo.SemanticVersion('1.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.0.1-*') <= dbo.SemanticVersion('1.0.1') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.1.*') > dbo.SemanticVersion('1.0.9') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.1.*') <= dbo.SemanticVersion('1.2.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.*') <= dbo.SemanticVersion('2.0.0') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('1.*') > dbo.SemanticVersion('0.9.9-beta-219') THEN 'Success' ELSE 'Failure' END
    SELECT CASE WHEN dbo.SemanticVersion('*') <= dbo.SemanticVersion('0.0.1-alpha-1') THEN 'Success' ELSE 'Failure' END
    
  5. ==============================

    5.두 단계는 먼저 소수점의 왼쪽이 오른쪽을 비교.

    두 단계는 먼저 소수점의 왼쪽이 오른쪽을 비교.

    가능한 해결책:

    declare @v1 varchar(100) = '5.12'
    declare @v2 varchar(100) = '5.8'
    
    select case 
        when CONVERT(int, LEFT(@v1, CHARINDEX('.', @v1)-1)) < CONVERT(int, LEFT(@v2, CHARINDEX('.', @v2)-1)) then 'v2 is newer'
        when CONVERT(int, LEFT(@v1, CHARINDEX('.', @v1)-1)) > CONVERT(int, LEFT(@v2, CHARINDEX('.', @v2)-1)) then 'v1 is newer'
        when CONVERT(int, RIGHT(@v1, LEN(@v1) - CHARINDEX('.', @v1))) < CONVERT(int, RIGHT(@v2, LEN(@v2) - CHARINDEX('.', @v2))) then 'v2 is newer'
        when CONVERT(int, RIGHT(@v1, LEN(@v1) - CHARINDEX('.', @v1))) > CONVERT(int, RIGHT(@v2, LEN(@v2) - CHARINDEX('.', @v2))) then 'v1 is newer'
        else 'same!' end as 'Version Test'
    
  6. ==============================

    6.당신은 HIERARCHYID 사용할 수 있습니다 어떤 당신이 마지막에 /를 넣고 문자열의 시작을 주조로 사용할 수 있습니다

    당신은 HIERARCHYID 사용할 수 있습니다 어떤 당신이 마지막에 /를 넣고 문자열의 시작을 주조로 사용할 수 있습니다

    EG

    SELECT CASE WHEN 캐스트 ( '/ 5.12 /'HIERARCHYID 등)> 캐스팅 ( '/ 5.8 /'HIERARCHYID 등) THEN ELSE 'Y', 'N'END

    즉, Y를 반환

  7. ==============================

    7.AF 제안로서 당신은 우선은 이런 식으로 뭔가를 시도 할 수 parsename를 사용하여 할 수있는 또 하나 개의 방법이 주어진 모든 해답에서 INT 부분과 다음 소수 부분 .Apart을 비교할 수 있습니다

    AF 제안로서 당신은 우선은 이런 식으로 뭔가를 시도 할 수 parsename를 사용하여 할 수있는 또 하나 개의 방법이 주어진 모든 해답에서 INT 부분과 다음 소수 부분 .Apart을 비교할 수 있습니다

     case when cast(@var as int)>cast(@var2 as int) then 'Y' 
     when cast(PARSENAME(@var,1) as int) > cast(PARSENAME(@var2,1) as int) THEN 'Y'
    
    
     Declare @var float
     Declare @var2 float
     set @var=5.14
     set @var2=5.8
     Select case when cast(@var as int)>cast(@var2 as int) then 'Y' 
     when cast(PARSENAME(@var,1) as int)> cast(PARSENAME(@var2,1) as int) THEN 'Y'
     else 'N' END
    
  8. ==============================

    8.문자열이 아닌 어떤 문자열에 보관하지 마십시오. 바이트와 ​​구현 적절한 비교 로직의 순서로 버전을 저장하는 것이 - 대체 (일부 시간에 허용 C #에서) 자신의 데이터 형식을 만드는 것입니다.

    문자열이 아닌 어떤 문자열에 보관하지 마십시오. 바이트와 ​​구현 적절한 비교 로직의 순서로 버전을 저장하는 것이 - 대체 (일부 시간에 허용 C #에서) 자신의 데이터 형식을 만드는 것입니다.

  9. ==============================

    9.당신은 질문에 그렇게 말하지 않지만, 톰톰의 대답에서 귀하의 의견은 [소수] [D]와 같은 버전 번호를 저장하는 제안합니다. 나는이 같은 테이블이 추측 :

    당신은 질문에 그렇게 말하지 않지만, 톰톰의 대답에서 귀하의 의견은 [소수] [D]와 같은 버전 번호를 저장하는 제안합니다. 나는이 같은 테이블이 추측 :

    CREATE TABLE ReleaseHistory (
      VersionNumber DECIMAL(6,3) NOT NULL
    );
    GO
    
    INSERT INTO ReleaseHistory (
      VersionNumber
    )
    VALUES
      (5.12),
      (5.8),
      (12.34),
      (3.14),
      (0.78),
      (1.0);
    GO
    

    다음 쿼리는 그들이 출시되는 순서에 의해 순위 버전으로 시도이다 :

    SELECT
      VersionNumber,
      RANK() OVER (ORDER BY VersionNumber) AS ReleaseOrder
    FROM ReleaseHistory;
    

    그것은 다음과 같은 결과 집합을 생성합니다

    VersionNumber                           ReleaseOrder
    --------------------------------------- --------------------
    0.780                                   1
    1.000                                   2
    3.140                                   3
    5.120                                   4
    5.800                                   5
    12.340                                  6
    

    이것은 우리가 기대하지 않습니다. 버전 5.8은 버전 5.12 이전에 릴리스 된!

    제대로 버전 번호를 평가하기 위해 전공 및 부전공 구성 요소에 버전 번호를 분할합니다. 이 작업을 수행하는 한 가지 방법은 기간에 문자열 및 분할에 소수점 값을 변환하는 것입니다. 이에 대한 T-SQL 구문 (언어가 문자열 처리를 위해 설계되지 않았습니다) 못생긴 :

    WITH VersionStrings AS (
      SELECT CAST(VersionNumber AS VARCHAR(6)) AS VersionString
      FROM ReleaseHistory
    ),
    VersionNumberComponents AS (
      SELECT
        CAST(SUBSTRING(VersionString, 1, CHARINDEX('.', VersionString) - 1) AS INT) AS MajorVersionNumber,
        CAST(SUBSTRING(VersionString, CHARINDEX('.', VersionString) + 1, LEN(VersionString) - CHARINDEX('.', VersionString)) AS INT) AS MinorVersionNumber
      FROM VersionStrings
    )
    SELECT
      CAST(MajorVersionNumber AS VARCHAR(3)) + '.' + CAST(MinorVersionNumber AS VARCHAR(3)) AS VersionString,
      RANK() OVER (ORDER BY MajorVersionNumber, MinorVersionNumber) AS ReleaseOrder
    FROM VersionNumberComponents;
    

    그러나 예상 결과를 제공합니다 :

    VersionString ReleaseOrder
    ------------- --------------------
    0.780         1
    1.0           2
    3.140         3
    5.120         4
    5.800         5
    12.340        6
    

    톰톰 대답으로, 진수는 버전 번호를 저장하는 안 좋은 유형입니다. 두 개의 양의 정수 열, 주 버전 번호와 마이너 버전 번호를 포함하는 기타를 포함하는 하나의 버전 번호를 저장하기 위해 더 좋을 것이다.

  10. ==============================

    10.이 SeanW의 대답을 기반으로하지만,이 솔루션은 다음과 같은 형식 [주요] 수 있습니다. [작은]. [빌드]. 그것은 아마도 SQL 2K에 사용되는 커서는 옵션이 아닌 경우.

    이 SeanW의 대답을 기반으로하지만,이 솔루션은 다음과 같은 형식 [주요] 수 있습니다. [작은]. [빌드]. 그것은 아마도 SQL 2K에 사용되는 커서는 옵션이 아닌 경우.

    declare @v1 varchar(100) = '1.4.020'
    declare @v2 varchar(100) = '1.4.003'
    
    declare @v1_dot1_pos smallint   /*position - 1st version - 1st dot */
    declare @v1_dot2_pos smallint   /*position - 1st version - 2nd dot */
    declare @v2_dot1_pos smallint   /*position - 2nd version - 1st dot */
    declare @v2_dot2_pos smallint   /*position - 2nd version - 2nd dot */
    
    -------------------------------------------------
    -- get the pos of the first and second dots
    -------------------------------------------------
    SELECT 
    @v1_dot1_pos=CHARINDEX('.', @v1),
    @v2_dot1_pos=CHARINDEX('.', @v2),
    @v1_dot2_pos=charindex( '.', @v1, charindex( '.', @v1 ) + 1 ),
    @v2_dot2_pos=charindex( '.', @v2, charindex( '.', @v2 ) + 1 )
    
    
    -------------------------------------------------
    -- break down the parts
    -------------------------------------------------
    DECLARE @v1_major int, @v2_major int
    DECLARE @v1_minor int, @v2_minor int
    DECLARE @v1_build int, @v2_build int 
    
    SELECT 
        @v1_major = CONVERT(int,LEFT(@v1,@v1_dot1_pos-1)),
        @v1_minor = CONVERT(int,SUBSTRING(@v1,@v1_dot1_pos+1,(@v1_dot2_pos-@v1_dot1_pos)-1)),
        @v1_build = CONVERT(int,RIGHT(@v1,(LEN(@v1)-@v1_dot2_pos))),
        @v2_major = CONVERT(int,LEFT(@v2,@v2_dot1_pos-1)),
        @v2_minor = CONVERT(int,SUBSTRING(@v2,@v2_dot1_pos+1,(@v2_dot2_pos-@v2_dot1_pos)-1)),
        @v2_build = CONVERT(int,RIGHT(@v2,(LEN(@v2)-@v2_dot2_pos)))
    
    
    -------------------------------------------------
    -- return the difference
    -------------------------------------------------
    SELECT
        Case    
            WHEN @v1_major < @v2_major then 'v2 is newer'
            WHEN @v1_major > @v2_major then 'v1 is newer'
            WHEN @v1_minor < @v2_minor then 'v2 is newer'
            WHEN @v1_minor > @v2_minor then 'v1 is newer'
            WHEN @v1_build < @v2_build then 'v2 is newer'
            WHEN @v1_build > @v2_build then 'v1 is newer'
            ELSE '!Same'
        END
    
  11. ==============================

    11.구현 된 솔루션 :

    구현 된 솔루션 :

    CREATE FUNCTION [dbo].[version_compare]
    (
        @v1 VARCHAR(5), @v2 VARCHAR(5)
    )
    RETURNS tinyint
    AS
    BEGIN
        DECLARE @v1_int tinyint, @v1_frc tinyint, 
                @v2_int tinyint, @v2_frc tinyint, 
                @ResultVar tinyint
    
        SET @ResultVar = 0
    
        SET @v1_int = CONVERT(tinyint, LEFT(@v1, CHARINDEX('.', @v1) - 1))
        SET @v1_frc = CONVERT(tinyint, RIGHT(@v1, LEN(@v1) - CHARINDEX('.', @v1)))
        SET @v2_int = CONVERT(tinyint, LEFT(@v2, CHARINDEX('.', @v2) - 1))
        SET @v2_frc = CONVERT(tinyint, RIGHT(@v2, LEN(@v2) - CHARINDEX('.', @v2)))
    
        SELECT @ResultVar = CASE
            WHEN @v2_int > @v1_int THEN 2
            WHEN @v1_int > @v2_int THEN 1
            WHEN @v2_frc > @v1_frc THEN 2
            WHEN @v1_frc > @v2_frc THEN 1
        ELSE 0 END
    
        -- Return the result of the function
        RETURN @ResultVar
    END
    GO
    
  12. ==============================

    12.이 재귀 쿼리는 '어떤 변환 것입니다 .- 비교 문자열로 분리 된 버전 번호는 왼쪽 패딩 10 자 따라서 또는 빌드 번호가없는 버전을 비교할 수 있도록하고 숫자가 아닌 문자를 수용 각 요소를 :

    이 재귀 쿼리는 '어떤 변환 것입니다 .- 비교 문자열로 분리 된 버전 번호는 왼쪽 패딩 10 자 따라서 또는 빌드 번호가없는 버전을 비교할 수 있도록하고 숫자가 아닌 문자를 수용 각 요소를 :

    WITH cte (VersionNumber) AS (
      SELECT '1.23.456' UNION ALL
      SELECT '2.3'      UNION ALL
      SELECT '0.alpha-3'
      ),
      parsed (VersionNumber, Padded) AS (
      SELECT
        CAST(SUBSTRING(VersionNumber, CHARINDEX('.', VersionNumber) + 1, LEN(VersionNumber)) + '.' AS NVARCHAR(MAX)),
        CAST(RIGHT(REPLICATE('0', 10) + LEFT(VersionNumber, CHARINDEX('.', VersionNumber) - 1), 10) AS NVARCHAR(MAX))
      FROM cte
      UNION ALL
      SELECT
        SUBSTRING(VersionNumber, CHARINDEX('.', VersionNumber) + 1, LEN(VersionNumber)),
        Padded + RIGHT(REPLICATE('0', 10) + LEFT(VersionNumber, CHARINDEX('.', VersionNumber) - 1), 10)
      FROM parsed WHERE CHARINDEX('.', VersionNumber) > 0
      )
    SELECT Padded
    FROM parsed
    WHERE VersionNumber = ''
    ORDER BY Padded;
    
    Padded
    ------------------------------
    0000000000000alpha-3
    000000000100000000230000000456
    00000000020000000003
    
  13. ==============================

    13.여기에 내가에 유래에서 발견 된 일부 코드를 수정하고 일부 나 자신을 써서 한 것입니다. 이 때문에 나를 어떻게 생각하는지 알려 주시기 바랍니다 코드의 버전 1입니다. 사용 예 및 테스트 케이스는 코드 주석에 있습니다.

    여기에 내가에 유래에서 발견 된 일부 코드를 수정하고 일부 나 자신을 써서 한 것입니다. 이 때문에 나를 어떻게 생각하는지 알려 주시기 바랍니다 코드의 버전 1입니다. 사용 예 및 테스트 케이스는 코드 주석에 있습니다.

    SQL 2016 이상을 사용하지 않는 당신이 STRING_SPLIT에 액세스 할 수없는 경우 먼저이 기능을 만듭니다

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Author:      <Author,,Name>
    -- Create date: <Create Date,,>
    -- Description: modified from https://stackoverflow.com/questions/10914576/t-sql-split-string/42000063#42000063
    -- =============================================
    CREATE FUNCTION [dbo].[SplitStringToRows]
    (   
        @List VARCHAR(4000) 
        , @Delimiter VARCHAR(50)
    )
    RETURNS TABLE 
    AS
    RETURN 
    (
        --For testing
        -- SELECT * FROM SplitStringToRows ('1.0.123','.')
        -- DECLARE @List VARCHAR(MAX) = '1.0.123', @Delimiter VARCHAR(50) = '.';
    
        WITH Casted AS
        (
            SELECT CAST(N'<x>' + REPLACE((SELECT REPLACE(@List,@Delimiter,N'§§Split$me$here§§') AS [*] FOR XML PATH('')),N'§§Split$me$here§§',N'</x><x>') + N'</x>' AS XML) AS SplitMe
        )
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [Index]
        , x.value(N'.',N'nvarchar(max)') AS Part 
        FROM Casted
        CROSS APPLY SplitMe.nodes(N'/x') AS A(x)
    )
    

    그런 다음이 함수를 만들 :

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Author:      Soenhay
    -- Create date: 7/1/2017
    -- Description: Returns -1 if VersionStringA is less than VersionStringB.
    --              Returns 0 if VersionStringA equals VersionStringB.
    --              Returns 1 if VersionSTringA is greater than VersionStringB.
    -- =============================================
    CREATE FUNCTION dbo.CompareVersionStrings
    (   
        @VersionStringA VARCHAR(50)
        ,@VersionStringB VARCHAR(50)
    )
    RETURNS TABLE 
    AS
    RETURN 
    (
        --CurrentVersion should be of the form:
        --major.minor[.build[.revision]] 
        --This is the same as the versioning system used in c#.
        --For applications the build and revision numbers will by dynamically set based on the current date and time of the build. 
        --Example: [assembly: AssemblyFileVersion("1.123.*")]//http://stackoverflow.com/questions/15505841/the-version-specified-for-the-file-version-is-not-in-the-normal-major-minor-b
        --Each component should be between 0 and 65534 ( UInt16.MaxValue - 1 )
        --Max version number would be 65534.65534.65534.65534
    
        --For Testing 
        -- SELECT * FROM dbo.CompareVersionStrings('', '')
        -- SELECT * FROM dbo.CompareVersionStrings('asdf.asdf', 'asdf.asdf') --returns 0
        -- SELECT * FROM dbo.CompareVersionStrings('asdf', 'fdas') --returns -1 
        -- SELECT * FROM dbo.CompareVersionStrings('zasdf', 'fdas') --returns 1 
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.123.123', '1.1.123.123')  --Should return -1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.123.123', '1.0.123.123')  --Should return 0
        -- SELECT * FROM dbo.CompareVersionStrings('1.1.123.123', '1.0.123.123')  --Should return 1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.123.123', '1.0.124.123')  --Should return -1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.124.123', '1.0.123.123')  --Should return 1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.123.123', '1.0.123.124')  --Should return -1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0.123.124', '1.0.123.123')  --Should return 1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0', '1.1')  --Should return -1
        -- SELECT * FROM dbo.CompareVersionStrings('1.0', '1.0')  --Should return 0
        -- SELECT * FROM dbo.CompareVersionStrings('1.1', '1.0')  --Should return 1
        -- Declare @VersionStringA VARCHAR(50) = '' ,@VersionStringB VARCHAR(50) = '' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.0.123.123' ,@VersionStringB VARCHAR(50) = '1.1.123.123' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.1.123.123' ,@VersionStringB VARCHAR(50) = '1.1.123.123' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.2.123.123' ,@VersionStringB VARCHAR(50) = '1.1.123.123' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.1.123' ,@VersionStringB VARCHAR(50) = '1.1.123.123' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.1.123.123' ,@VersionStringB VARCHAR(50) = '1.1.123' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.1' ,@VersionStringB VARCHAR(50) = '1.1' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.2' ,@VersionStringB VARCHAR(50) = '1.1' ;
        -- Declare @VersionStringA VARCHAR(50) = '1.1' ,@VersionStringB VARCHAR(50) = '1.2' ;
    
        WITH 
        Indexes AS
        (
            SELECT 1 AS [Index]
                , 'major' AS Name
            UNION
            SELECT 2
                , 'minor'
            UNION
            SELECT 3
                , 'build'
            UNION
            SELECT 4
                , 'revision'
        )
        , SplitA AS
        (
            SELECT * FROM dbo.SplitStringToRows(@VersionStringA, '.')
        )
        , SplitB AS
        (
            SELECT * FROM dbo.SplitStringToRows(@VersionStringB, '.')
        )
        SELECT
            CASE WHEN major = 0 THEN
                    CASE WHEN minor = 0 THEN
                                        CASE WHEN build = 0 THEN
                                                            CASE WHEN revision = 0 THEN 0
                                                            ELSE revision END
                                            ELSE build END
                        ELSE minor END
                ELSE major END AS Compare
        FROM
        (
            SELECT 
                 MAX(CASE WHEN [Index] = 1 THEN Compare ELSE NULL END) AS major
                ,MAX(CASE WHEN [Index] = 2 THEN Compare ELSE NULL END) AS minor
                ,MAX(CASE WHEN [Index] = 3 THEN Compare ELSE NULL END) AS build
                ,MAX(CASE WHEN [Index] = 4 THEN Compare ELSE NULL END) AS revision
            FROM(
                SELECT [Index], Name, 
                    CASE WHEN A = B THEN 0
                        WHEN A < B THEN -1
                        WHEN A > B THEN 1
                        END AS Compare
                FROM
                (
                    SELECT 
                         i.[Index]
                        ,i.Name
                        ,ISNULL(a.Part, 0) AS A
                        ,ISNULL(b.Part, 0) AS B
                    FROM Indexes i
                        LEFT JOIN SplitA a
                    ON  a.[Index] = i.[Index]
                        LEFT JOIN SplitB b
                    ON  b.[Index] = i.[Index]
                ) q1
            ) q2
        ) q3
    
    )
    GO
    
  14. ==============================

    14.I,이 함수 (상기 에바 레이스 ()에서 영감) 만들었다 :

    I,이 함수 (상기 에바 레이스 ()에서 영감) 만들었다 :

    CREATE or alter function dbo.IsVersionNewerThan
    (
        @Source nvarchar(max),
        @Target nvarchar(max)
    )
    RETURNS table
    as 
    /*
    -1 : target has higher version number (later version)
    0 : same
    1 : source has higher version number (later version)
    
    test harness:
    ; WITH tmp
    AS
    (
        SELECT '1.0.0.5' AS Version
        UNION ALL SELECT '0.0.0.0'
        UNION ALL SELECT '1.5.0.6'
        UNION ALL SELECT '2.0.0'
        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 tmp.version, isGreather from tmp
    outer apply (select * from dbo.IsVersionNewerThan(tmp.Version, '2.0.0.0')) as IsG
    
    */ 
        return (
            select CASE 
                when cast('/' + @Source + '/' as hierarchyid) > cast('/' + @Target + '/' as hierarchyid) THEN 1 
                when @Source = @Target then 0
                else -1 
            end as IsGreather
        )
    go
    

    테스트 스크립트는 주석으로 포함되어 있습니다. 당신이 '1.5.06.2'(제로주의)와 같은 버전을 가지고 있지 않는 한 그것은 한 작품. SQL Server는이 기능은 성능을 잘 is_inlineable = 1, 징조를 가지고 생각합니다.

    그럼 내 SQL 코드는 다음과 같을 수 있습니다 :

    declare @version varchar(10) = '2.30.1.12'
    set @version = '2.30.1.1'
    if exists(select * from dbo.IsVersionNewerThan(@version,'2.30.1.12') where IsGreather >= 0)
    BEGIN
        print 'yes'
    end
    else print 'no'
    
  15. ==============================

    15.난 당신이 가장 짧은 대답을 줄 수 있습니다.

    난 당신이 가장 짧은 대답을 줄 수 있습니다.

    with cte as (
        select  7.11 as ver
        union all
        select 7.6
    )
    
    select top 1 ver from cte
          order by parsename(ver, 2), parsename(cast(ver as float), 1)
    
  16. ==============================

    16.어쩌면 값으로 빌드 번호를 변환하는 빌드 버전 사이의 계층 구조를 이해하는 데 도움이 될 수 있습니다.

    어쩌면 값으로 빌드 번호를 변환하는 빌드 버전 사이의 계층 구조를 이해하는 데 도움이 될 수 있습니다.

    DECLARE @version VARCHAR(25), @dot1 AS TINYINT, @dot2 AS TINYINT, @dot3 AS TINYINT, @MaxPower AS TINYINT, @Value AS BIGINT
    SELECT @version = CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR) --'14.0.1000.169' --'10.50.1600'
    SELECT @dot1 = CHARINDEX('.', @version, 1)
    SELECT @dot2 = CHARINDEX('.', @version, @dot1 + 1)
    SELECT @dot3 = CHARINDEX('.', @version, @dot2 + 1)
    SELECT @dot3 = CASE
        WHEN @dot3 = 0 THEN LEN(@version) + 1
        ELSE @dot3
    END
    
    SELECT @MaxPower = MAX(DotColumn) FROM (VALUES (@dot1-1), (@dot2-@dot1-1), (@dot3-@dot2-1)) AS DotTable(DotColumn)
    SELECT @Value = POWER(10, @MaxPower)
    --SELECT @version, @dot1, @dot2, @dot3, @MaxPower, @Value
    
    SELECT 
    --  @version AS [Build], 
        CAST(LEFT(@version, @dot1-1) AS INT) * POWER(@Value, 3) +
        CAST(SUBSTRING(@version, @dot1+1, @dot2-@dot1-1) AS INT) * POWER(@Value, 2) +
        CAST(SUBSTRING(@version, @dot2+1, @dot3-@dot2-1) AS INT) * @Value +
        CASE
            WHEN @dot3 = LEN(@version)+1 THEN CAST(0 AS INT)
            ELSE CAST(SUBSTRING(@version, @dot3+1, LEN(@version)-@dot3) AS INT)
        END AS [Value]
    
  17. from https://stackoverflow.com/questions/11364242/how-to-compare-software-versions-using-sql-server by cc-by-sa and MIT license