2014-03-05 86 views
0

我正在嘗試創建一個接受(SQL Server)數據庫表的存儲過程,並返回每列的摘要。如何計算給定表和列名稱的數據庫列統計信息?

大多數我想要的是從INFORMATION_SCHEMA.COLUMNS可用,但對於數字列我想包括一些基本的統計數據,如平均/分/最大。

我的計劃是有一個這樣的查詢:

SELECT 
    TABLE_NAME, 
    COLUMN_NAME, 
    DATA_TYPE AS DataType, 
    CASE 
     WHEN DATA_TYPE IN (
     'bigint', 'bit', 'date', 'datetime', 'datetime2', 
     'datetimeoffset', 'decimal', 'float', 'int', 'money', 
     'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 
     'time', 'timestamp', 'tinyint') 
     THEN dbo.GetMin(TABLE_NAME, COLUMN_NAME) 
     ELSE NULL 
    END AS MinSql 
    FROM INFORMATION_SCHEMA.COLUMNS 

和用戶定義的函數GetMin時,他的屍體是這樣的:

DECLARE @Sql varchar(MAX) = CONCAT(
    'SELECT MIN(', 
    @ColumnName, 
    ') FROM ', 
    @TableName 
    ''';' 
); 

EXEC(@Sql); 

不幸的是,來電EXEC不允許在UDF內部。

我怎麼可以:

  1. 返回給在服用MIN(和其它數據)的所有列的表名和列名,或

  2. 循環統計像MIN,?

+0

http://www.sommarskog.se/dynamic_sql.html – Jodrell

回答

1

報價 「通常情況下時(不)使用動態SQL」航向 article from my comment的,

一個常見的問題是,爲什麼下面不工作:

CREATE PROCEDURE my_proc @tablename sysname AS 
    SELECT * FROM @tablename 

正如我們所看到的,我們可以使t他的過程通過動態的 SQL進行工作,但是我們也應該清楚,我們並沒有獲得在存儲過程中生成動態SQL的優勢 。您也可以僅從 以及從客戶端發送動態SQL。所以,確定:1)如果SQL語句非常複雜,則可以節省一些網絡流量,並且可以執行封裝操作 。 2)正如我們所看到的,從SQL 2005開始,有 方法來處理權限。不過,這個不好主意。

+0

讓我確定我已經正確理解了這一點。使用動態SQL來彙總任意表是不好的。沒有像存儲過程,函數或其他任何可以使其可接受的工具。如果我要用另一種編程語言生成SQL,並從那裏執行SQL,那就沒問題了。有許多類似的存儲過程,每個表有一個也是可以接受的。 –

+0

@RichieCotton爲了壓縮,存儲過程非常適合重複受益於緩存查詢計劃的查詢。如果您傳遞的參數會極大地影響查詢的結構,則緩存的查詢計劃最好是開銷。將參數化查詢傳遞給'sp_executesql'會更好,這將在查詢碰巧是相同的時候受益。你會注意到,這是.Net框架和實體框架中的大部分代碼都在底層。 – Jodrell

相關問題