2013-01-23 175 views
10

我想從表中獲取列的所有列的數據類型,數據長度和該列中最長值的長度。列出最大長度和最大長度的所有SQL列

我有這樣的SQL用於獲取列及其數據類型和長度:

SELECT 
    Object_Name(c.object_id), 
    c.name 'Column Name', 
    t.Name 'Data type', 
    c.max_length 'Max Length' 
FROM  
    sys.columns c 
INNER JOIN 
    sys.types t ON c.system_type_id = t.system_type_id 
WHERE 
    c.object_id = OBJECT_ID('MyTable') 

,我有這個SQL爲獲得一個價值

SELECT Max(Len(MyColumn)) 
FROM MyTable 

的最大長度,但我不能圖瞭解如何將它們結合起來。

我使用MSSQL 2008年

+0

你使用什麼類型的數據庫? –

+0

你正在使用什麼[RDBMS](http://en.wikipedia.org/wiki/Relational_database_management_system)? 'SQL Server'? 'MySQL'? 'Oracle'? 'DB2'? –

+1

SQL是多種數據庫產品共享的標準語言。如果您在詢問SQL Server,請將其添加爲單獨的標籤。 –

回答

10

感謝您的建議。我已經想出了以下解決方案。它給我提供了我需要的數據,但會有興趣看看它是否可以提高效率。

declare @results table 
(
ID varchar(36), 
TableName varchar(250), 
ColumnName varchar(250), 
DataType varchar(250), 
MaxLength varchar(250), 
Longest varchar(250), 
SQLText varchar(250) 
) 

INSERT INTO @results(ID,TableName,ColumnName,DataType,MaxLength,Longest,SQLText) 
SELECT 
    NEWID(), 
    Object_Name(c.object_id), 
    c.name, 
    t.Name, 
    case 
     when t.Name != 'varchar' Then 'NA' 
     when c.max_length = -1 then 'Max' 
     else CAST(c.max_length as varchar) 
    end, 
    'NA', 
    'SELECT Max(Len(' + c.name + ')) FROM ' + OBJECT_SCHEMA_NAME(c.object_id) + '.' + Object_Name(c.object_id) 
FROM  
    sys.columns c 
INNER JOIN 
    sys.types t ON c.system_type_id = t.system_type_id 
WHERE 
    c.object_id = OBJECT_ID('MyTable')  


DECLARE @id varchar(36) 
DECLARE @sql varchar(200) 
declare @receiver table(theCount int) 

DECLARE length_cursor CURSOR 
    FOR SELECT ID, SQLText FROM @results WHERE MaxLength != 'NA' 
OPEN length_cursor 
FETCH NEXT FROM length_cursor 
INTO @id, @sql 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    INSERT INTO @receiver (theCount) 
    exec(@sql) 

    UPDATE @results 
    SET Longest = (SELECT theCount FROM @receiver) 
    WHERE ID = @id 

    DELETE FROM @receiver 

    FETCH NEXT FROM length_cursor 
    INTO @id, @sql 
END 
CLOSE length_cursor 
DEALLOCATE length_cursor 


SELECT 
    TableName, 
    ColumnName, 
    DataType, 
    MaxLength, 
    Longest 
FROM 
    @results 
+0

這工作得很好 - 只是添加了幾個位來允許列名與空格,並按列表中的順序排列列。 – bhs

+0

反正從整列中獲取最大數值? – AskMe

+0

對於感興趣的讀者,[本文](http://cc.davelozinski.com/code/sql-code/sql-to-get-max-length-of-values-in-every-table-column)詳細代碼用於不需要使用遊標的類似功能。 –

2
SELECT TOP 1 WITH TIES 
     Object_Name(c.object_id) ObjectName, 
     c.name [Column Name], 
     t.Name [Data type], 
     c.max_length [Max Length] 
    FROM  
     sys.columns c 
    INNER JOIN 
     sys.types t ON c.system_type_id = t.system_type_id 
    WHERE 
     c.object_id = OBJECT_ID('MyTable') 
    ORDER BY c.max_length DESC 
+0

可能用於檢索具有目錄視圖的列級別元數據需要添加加入此條件c.user_type_id = t。user_type_id也是 –

+1

sys.columns視圖中上面的max_length字段是字段值可以具有的最大長度。這不是MyTable中字段數據的最大長度。 OP想要的是比較數據類型的長度與該字段中數據的最大實際長度。 –

0

答案是相當複雜的。您需要使用動態SQL將查詢放在一起或在Excel中完成工作。您需要將來自系統表的元數據(我將使用Information_Schema.Columns)與來自表本身的數據結合使用。

如何做到這一點在我的書的第84-90頁上有解釋Data Analysis Using SQL and Excel。這個網站的答案太長了。

2

上面的查詢

SELECT 
    Object_Name(c.object_id), 
    c.name 'Column Name', 
    t.name 'Data type', 
    c.max_length 'Max Length' 
FROM  
    sys.columns c 
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id 
WHERE 
    c.object_id = OBJECT_ID('tablename') 
4

修正這是我使用的個人資料,可能是有用的數據。只需將「您的表格名稱」更改爲您的表格名稱即可。這是爲了向您展示可以修剪列的位置。

DECLARE @YourTableName sysname; 
DECLARE @sql nvarchar(MAX) = '' 
SET @YourTableName = YOUR TABLE NAME 
CREATE TABLE #resultsTable (columnName varchar(100), columnLargestValueInData int, columnMaxLength int) 

DECLARE @whileIter int = 1 
DECLARE @whileTotal int 

SELECT @whileTotal = COUNT(*) FROM sys.columns c 
          INNER JOIN 
           sys.types t ON c.user_type_id = t.user_type_id 
          WHERE 
           c.object_id = OBJECT_ID(@YourTableName) 
-- print 'whileTotal: ' + CONVERT(VARCHAR,@whileTotal) -- used for testing 
WHILE @whileIter <= @whileTotal 
BEGIN 

SELECT @sql = N'INSERT INTO #resultsTable (columnName, columnLargestValueInData, columnMaxLength) SELECT ''' + sc.name + ''' AS columnName, max(len([' + sc.name + '])), ' + CONVERT(varchar,sc.max_length) + ' FROM [' + t.name + ']' 
FROM sys.tables AS t 
INNER JOIN sys.columns AS sc ON t.object_id = sc.object_id 
INNER JOIN sys.types AS st ON sc.system_type_id = st.system_type_id 
WHERE column_id = @whileIter 
AND t.name = @YourTableName 
AND st.name IN ('char', 'varchar', 'nchar', 'nvarchar') 

PRINT @sql 

exec sp_executesql @sql 
SET @whileIter += 1 
END 
SELECT * FROM #resultsTable 

TRUNCATE TABLE #resultsTable 
DROP TABLE #resultsTable 
+2

這是爲什麼被低估?與大多數'答案'不同,它實際上給出了所有列中的最大數據長度(與列限制相對) –

-2

稍作修改,但作品一種享受。

SELECT 
    Object_Name(c.object_id), 
    c.name 'Column Name', 
    t.name 'Data type', 
    c.max_length 'Max Length', 
    MAX(LEN(C.NAME)) 
FROM  
    sys.columns c 
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id 
WHERE 
    c.object_id = OBJECT_ID('<table name>') 
GROUP BY 
    Object_Name(c.object_id), 
    c.name , 
    t.name , 
    c.max_length 
+3

沒有MAX(LEN(C.NAME))給出了列名稱的長度而不是內容的長度的列 – Tod

0

add:和t.user_type_id = 167,否則,你會得到dups的非varchars。我知道還有其他類型,這是後c.object_id = OBJECT_ID(@YourTableName)

0

這是我多年來使用一個版本的快速解決特定表

。它用一個下劃線替代空格,給出真實的數據長度和尾部空格。

set nocount on; 
declare @TableName varchar(150) = 'TableName'; 
declare @Schema varchar(20) = 'TableSchema'; 
declare @Columns varchar(max); 
declare @Unpivot varchar(max); 
declare @SQL varchar(max); 

select @Columns = STUFF((
select ',max(len(replace([' + COLUMN_NAME + '],'' '',''_'')))[' + COLUMN_NAME + '/' 
     + isnull(ltrim(CHARACTER_MAXIMUM_LENGTH),DATA_TYPE) + ']' + CHAR(10) + CHAR(9) 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA = @Schema 
     and TABLE_NAME = @TableName 
order by ORDINAL_POSITION 
for XML PATH('')),1,1,'') 

select @Unpivot = STUFF((
select ',[' + COLUMN_NAME + '/' + isnull(ltrim(CHARACTER_MAXIMUM_LENGTH),DATA_TYPE) + ']' 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA = @Schema 
     and TABLE_NAME = @TableName 
order by ORDINAL_POSITION 
for XML PATH('')),1,1,'') 

select @SQL = 
'select DataSize, ColumnName [ColumnName/Size] 
from (
     select ' + @Columns + 'from [' + @Schema + '].[' + @TableName + '] 
     )x 
unpivot (DataSize for ColumnName in (' + @Unpivot + '))p' 

print (@SQL) 
exec (@SQL) 
0

請注意,上面提到的所有查詢都會報告一些「奇怪的」大小 - 特別是對於n ...類型(nvarchar/nchar)。這個略有修改的查詢修復了這個問題:

DECLARE @tableName AS NVARCHAR(200) = 'Items' 

SELECT 
    Object_Name(c.object_id) AS 'Table', 
    c.name AS 'Column Name', 
    t.name AS 'Data type', 
    CASE WHEN t.name LIKE 'n%' THEN c.max_length/2 ELSE c.max_length END AS 'Max Length' 
FROM  
    sys.columns c 
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id 
WHERE 
    c.object_id = OBJECT_ID(@tableName)