2013-01-23 177 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)