Qual è il modo migliore per memorizzare System.Version in SQL Server?Tipo di dati per System.Version in sql server
Quando uso tipo varchar, frutto di ordine per asc è:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
Qual è il modo migliore per memorizzare System.Version in SQL Server?Tipo di dati per System.Version in sql server
Quando uso tipo varchar, frutto di ordine per asc è:
1.0.0.0
11.0.0.0
12.0.0.0
2.0.0.0
è possibile utilizzare una colonna varchar
si poteva ordinare come questo
SELECT *
FROM t_version
ORDER BY CAST('/' + vid + '/' AS HIERARCHYID)
SQL violino non è lavorando oggi, altrimenti avrei potuto mostrare una demo
Si prega di eseguire questo per test 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)
Suggerimento: puoi usare più facilmente 'VALUES' invece di' UNION ALL' per le risposte dimostrative: 'SELECT * FROM (VALUES ('1.0.0.0'), ('11 .0.0.0 ') ...) AS vid (vid) ORDINA DA ... ' – hvd
@hvd: Grazie per quello, sembra più pulito .. Ho aggiornato la mia risposta –
@hvd Normalmente mi astengo a meno che la domanda non sia taggata' sql-server -2008', o 2012 – RichardTheKiwi
Proprio conservarlo come un varchar normale, che è buono per le versioni fino a 4 parti utilizzando ParseName di dividere la stringa e l'ordine da 4 colonne separate.
cioè
ORDER BY PARSENAME(version,4),
PARSENAME(version,3),
PARSENAME(version,2),
PARSENAME(version,1)
+1 - molto elegante e nuovo per me! –
Sostenere ordinamento tra versioni lunghezze miste (ad esempio '1,2' vs '1.2.3.4'), una mappatura per un decimale può essere eseguita (come funzioni a valori di tabella in linea).
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
Dipendenza:
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
Confronto:
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 per la buona domanda –
Avete qualche altra colonna valutazione che possano aiutare a ordinare le versioni? – V4Vendetta
@ V4Vendetta no Non ce l'ho –