將System.Version存儲在SQL Server中的最佳方式是什麼?SQL服務器中的System.Version的數據類型
當我通過ASC使用VARCHAR類型,結果的順序是:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
將System.Version存儲在SQL Server中的最佳方式是什麼?SQL服務器中的System.Version的數據類型
當我通過ASC使用VARCHAR類型,結果的順序是:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
可以使用VARCHAR列
你可以命令這樣
SELECT *
FROM t_version
ORDER BY CAST('/' + vid + '/' AS HIERARCHYID)
SQL小提琴不今天工作,其他明智的我可以展示一個演示
請運行此測試荷蘭國際集團
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)
提示:你可以更容易地使用'VALUES'而不是'UNION ALL'作爲示範答案:'SELECT * FROM(VALUES('1.0.0.0'),('11 .0.0.0 ')...)AS vid(vid)ORDER BY ...' – hvd
@ hvd:謝謝你,那看起來更乾淨..我已經更新了我的回答 –
@hvd我通常不會回答,除非問題被標記爲'sql-server -2008「,或2012 – RichardTheKiwi
其存儲爲一個正常的VARCHAR,這是良好的版本到4份使用PARSENAME拆分由4個獨立的列中的字符串和順序。
即
ORDER BY PARSENAME(version,4),
PARSENAME(version,3),
PARSENAME(version,2),
PARSENAME(version,1)
+1 - 非常優雅,給我一個新的! –
爲了支持混合長度的版本(例如「1.2」 VS「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
+1了很好的問題 –
你有任何其他有關列可能在訂購版本的幫助嗎? – V4Vendetta
@ V4Vendetta不,我沒有 –