Cách tốt nhất để lưu trữ System.Version trong SQL Server là gì?Kiểu dữ liệu cho System.Version trong máy chủ sql
Khi tôi sử dụng loại varchar, kết quả của trật tự bởi asc là:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
Cách tốt nhất để lưu trữ System.Version trong SQL Server là gì?Kiểu dữ liệu cho System.Version trong máy chủ sql
Khi tôi sử dụng loại varchar, kết quả của trật tự bởi asc là:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
bạn có thể sử dụng một cột VARCHAR
bạn có thể đặt hàng như
SELECT *
FROM t_version
ORDER BY CAST('/' + vid + '/' AS HIERARCHYID)
SQL fiddle này không làm việc ngày hôm nay, khôn ngoan khác tôi có thể đã cho thấy một bản demo
Hãy chạy thử nghiệm này để kiểm tra 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)
Mẹo: bạn có thể dễ dàng sử dụng 'VALUES' thay vì' UNION ALL' cho câu trả lời trình diễn: 'SELECT * FROM (VALUES ('1.0.0.0'), ('11 .0.0.0 ') ...) AS vid (vid) ORDER BY ... ' – hvd
@hvd: Cảm ơn vì điều đó, Điều đó có vẻ sạch hơn .. Tôi đã cập nhật câu trả lời của mình –
@hvd Tôi thường hạn chế trừ khi câu hỏi được gắn thẻ' sql-server -2008', hoặc 2012 – RichardTheKiwi
Chỉ lưu nó dưới dạng varchar bình thường, tốt cho phiên bản lên đến 4 phần sử dụng PARSENAME để chia chuỗi và thứ tự theo 4 cột riêng biệt.
ví dụ:
ORDER BY PARSENAME(version,4),
PARSENAME(version,3),
PARSENAME(version,2),
PARSENAME(version,1)
+1 - rất thanh lịch và một cái mới cho tôi! –
Để hỗ trợ đặt hàng giữa các độ dài phiên bản (ví dụ '1.2' vs '1.2.3.4') hỗn hợp, một ánh xạ đến một chữ số thập phân có thể được thực hiện (như các chức năng bảng nội tuyến có giá trị).
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
phụ thuộc:
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
So sánh:
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 cho câu hỏi tốt –
Bạn có bất cứ cột khác có liên quan mà có thể giúp đỡ trong việc đặt hàng các phiên bản? – V4Vendetta
@ V4Vendetta no I don't have it –