2014-05-22 58 views
1

爲了給出一些背景知識,我已經在我的環境中使用了少量的2000,2005,2008,2008 R2和2012服務器。我試圖通過TSQL以編程方式確定哪些服務器的級別足以與sys.dm_db_partition_stats綁定。爲了讓事情變得複雜,MS在2008 R2 R2,SP1和2012上正式推出了SP2,並且很好地將其包含在2014年RTM中。我想要做的是確定當前SQL Server的哪個版本是我正在運行上述查詢,然後比較該版本是否等於或高於上述SQL Server版本/修補程序級別。如果是這樣,我將使用新的DMV,否則我將使用折舊的sys.sysindexes DMV。使用TSQL的SQL Server版本的編程比較

只是爲了提醒你,這不像看主要產品版本那麼簡單。例如,如果我有一個SQL Server 2012 RTM服務器,它的級別高於SQL 2008 R2 SP2級別,但它在2012產品線上的級別不足,因此此例程必須明確構建一些邏輯

我試着迴避並查詢sys.all_views視圖,但具有諷刺意味的是早在2005年,sys.dm_db_partition_stats DMV就包含在SQL Server中,儘管試圖查詢它會導致查詢分析失敗。

我可以在TRY CATCH塊中運行一些DSQL的「不良實踐」解決方法,但坦率地說,這是一種糟糕的做法,我寧願以正確的方式做。

所以,我的問題:有沒有人有,他們可以共享,這將編程返回過程的真/假,如果在SQL Server版本融入一定的補丁集級別或更高?

我已經沒有問題想出自己的例行公事,但希望有人在那裏已經有類似的東西,我可以配合。

感謝,

約翰

回答

1

我想到了關於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 
0

根據你可以運行dm_db_partition_stats版本的描述,這將告訴你,1,如果你可以運行它,0,如果你不能。

SELECT CASE 
    WHEN @@VERSION LIKE '%7.00.623%' THEN 0 
    WHEN @@VERSION LIKE '%7.00.699%' THEN 0 
    WHEN @@VERSION LIKE '%7.00.842%' THEN 0 
    WHEN @@VERSION LIKE '%7.00.960%' THEN 0 
    WHEN @@VERSION LIKE '%7.00.0063%' THEN 0 
    WHEN @@VERSION LIKE '%8.00.094%' THEN 0 
    WHEN @@VERSION LIKE '%8.00.384%' THEN 0 
    WHEN @@VERSION LIKE '%8.00.532%' THEN 0 
    WHEN @@VERSION LIKE '%8.00.760%' THEN 0 
    WHEN @@VERSION LIKE '%8.00.2039%' THEN 0 
    WHEN @@VERSION LIKE '%9.00.0399.06%' THEN 0 
    WHEN @@VERSION LIKE '%9.00.2047%' THEN 0 
    WHEN @@VERSION LIKE '%9.00.3042%' THEN 0 
    WHEN @@VERSION LIKE '%9.00.4035%' THEN 0 
    WHEN @@VERSION LIKE '%9.00.5000%' THEN 0 
    WHEN @@VERSION LIKE '%00.00.0600.22%' THEN 0 
    WHEN @@VERSION LIKE '%00.00.2530%' THEN 0 
    WHEN @@VERSION LIKE '%00.00.4000%' THEN 0 
    WHEN @@VERSION LIKE '%00.00.5500%' THEN 0 
    WHEN @@VERSION LIKE '%00.50.0600.0%' THEN 0 
    WHEN @@VERSION LIKE '%00.50.2500' THEN 0 
    WHEN @@VERSION LIKE '%00.00.2000.6%' THEN 0 
    ELSE 1 
END 
+0

這沒有考慮CU或修補程序...坦率地說,我不想保持一個巨大的發佈號碼列表。感謝您的輸入! –