我想到了關於SQL存儲的各種編譯版本的一些選項,使用PowerShell的,等等,直到我意識到我真正的問題是轉換內部版本到這一點是很容易比較。在NVARCHAR格式中,9.xxx的構建版本實際上大於12.xxx,因爲它執行字母數字比較(例如9> 1)而不是數字比較(例如12> 9)。這總是扭曲我的成績不好的方式,所以我落得這樣做我本來想出了一個程序來生成版本轉換成4列的查詢結果,我可以很容易地運行對數字比較邏輯,在問候的主要,次要版本,生成版本和修訂版本。我把所有東西都放到IF EXISTS塊中,並根據需要得到我的真/假邏輯。
然後通過另一個論壇上,PARSENAME()函數被提及,那就是非常非常容易的路線可供選擇:
-- Will Wrap an IF EXISTS check around this query
SELECT 1
FROM (
SELECT CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), 4) AS INT) AS Major,
CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), 3) AS INT) AS Minor,
CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), 2) AS INT) AS Build,
CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), 1) AS INT) AS Revision
) t
WHERE (t.Major >= 10 AND t.Minor >= 50 AND t.Build >= 4000)
OR (t.Major >= 11 AND t.Build >= 3000)
OR (t.Major >= 12)
這是我想出了的情況下,任何人都關心的原代碼。一種使用表變量的方法;另一個CTE。
這裏唯一的缺點是它在2005年以前的任何版本中都不可行,因爲PIVOT函數,而PARSENAME函數沒有相同的問題。
-- NOTE: General Split Funcationality via http://sqlperformance.com/2012/07/t-sql-queries/split-strings
-- ### Table Var ### --
DECLARE @ProductVersion TABLE
(
RowNum INT IDENTITY(1,1),
Val INT
)
INSERT INTO @ProductVersion (Val)
SELECT y.i.value('(./text())[1]', 'nvarchar(128)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), '.', '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
-- Will Wrap an IF EXISTS check around this query
SELECT 1
FROM(
SELECT MAX([1]) AS Major, MAX([2]) AS Minor, MAX([3]) AS Build, MAX([4]) AS Revision
FROM @ProductVersion pv
PIVOT (MAX(pv.Val) FOR RowNum IN ([1], [2], [3], [4])) AS PivotTable
) t
WHERE (t.Major >= 10 AND t.Minor >= 50 AND t.Build >= 4000)
OR (t.Major >= 11 AND t.Build >= 3000)
OR (t.Major >= 12)
GO
-- ### CTE ### --
-- RowNum workaround per http://connect.microsoft.com/SQLServer/feedback/details/383888/fully-support-position-in-xquery
WITH ProductVersion AS
(
SELECT y.i.value('(./text())[1]', 'int') AS Val, row_number() over (partition by 0 order by nullif(0 * y.i.value('count(.)','int'), 0)) AS RowNum
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(128)), '.', '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
)
-- Will Wrap an IF EXISTS check around this query
SELECT 1
FROM(
SELECT MAX([1]) AS Major, MAX([2]) AS Minor, MAX([3]) AS Build, MAX([4]) AS Revision
FROM ProductVersion pv
PIVOT (MAX(pv.Val) FOR RowNum IN ([1], [2], [3], [4])) AS PivotTable
) t
WHERE (t.Major >= 10 AND t.Minor >= 50 AND t.Build >= 4000)
OR (t.Major >= 11 AND t.Build >= 3000)
OR (t.Major >= 12)
GO
這沒有考慮CU或修補程序...坦率地說,我不想保持一個巨大的發佈號碼列表。感謝您的輸入! –