sql-server-2005-reaching-table-row-size-limit
似乎返回每个定义的数据类型长度的行大小。我需要一个脚本,该脚本将为我提供表中的所有行,这些行的最大数据大小均超过建议的8024(无论MS建议如何)
#1 楼
尝试以下脚本:declare @table nvarchar(128)
declare @idcol nvarchar(128)
declare @sql nvarchar(max)
--initialize those two values
set @table = 'YourTable'
set @idcol = 'some id to recognize the row'
set @sql = 'select ' + @idcol +' , (0'
select @sql = @sql + ' + isnull(datalength(' + name + '), 1)'
from sys.columns
where object_id = object_id(@table)
and is_computed = 0
set @sql = @sql + ') as rowsize from ' + @table + ' order by rowsize desc'
PRINT @sql
exec (@sql)
行将按大小排序,因此您可以从上到下进行检查。
评论
是的,它不适用于varchar我同意。在此之前,您的查询未涵盖表格的所有列
– AnandPhadke
2012年10月5日,11:41
@AnandPhadke哪些列未涵盖?谢谢
– Jaime
2012年10月5日,12:42
为什么要为空列添加一个字节?那不是零字节吗?还是将其内部存储为#0?
– Paul
2014年10月20日18:39
@Paul,可变长度列(varchar,nvarchar ...)为零字节,但固定长度列(int,smallint ...)为实际数据类型长度,因此1是一种估计。 NULL是一个完整的Universe:)(还有一个用于标记NULL值的NULL位图掩码,它占用一些空间)。 stackoverflow.com/questions/4546273/…
– Jaime
14-10-21在9:01
@Paul,如果SQL Server使用任何数据压缩,它将存储为零字节。
–.d.popov
16 Jan 25 '13:13
#2 楼
我喜欢Jaime的上述内容。我添加了一些方括号来处理奇怪的列名。 declare @table nvarchar(128)
declare @idcol nvarchar(128)
declare @sql nvarchar(max)
--initialize those two values
set @table = 'YourTable'
set @idcol = 'some id to recognize the row'
set @sql = 'select ' + @idcol +' , (0'
select @sql = @sql + ' + isnull(datalength([' + name + ']), 1)'
from sys.columns where object_id = object_id(@table)
set @sql = @sql + ') as rowsize from ' + @table + ' order by rowsize desc'
PRINT @sql
exec (@sql)
#3 楼
我喜欢Speedcat的上述内容,并将其扩展为列出所有具有行数和总字节数的表。declare @table nvarchar(128)
declare @sql nvarchar(max)
set @sql = ''
DECLARE tableCursor CURSOR FOR
SELECT name from sys.tables
open tableCursor
fetch next from tableCursor into @table
CREATE TABLE #TempTable( Tablename nvarchar(max), Bytes int, RowCnt int)
WHILE @@FETCH_STATUS = 0
begin
set @sql = 'insert into #TempTable (Tablename, Bytes, RowCnt) '
set @sql = @sql + 'select '''+@table+''' "Table", sum(t.rowsize) "Bytes", count(*) "RowCnt" from (select (0'
select @sql = @sql + ' + isnull(datalength([' + name + ']), 1) '
from sys.columns where object_id = object_id(@table)
set @sql = @sql + ') as rowsize from ' + @table + ' ) t '
exec (@sql)
FETCH NEXT FROM tableCursor INTO @table
end
PRINT @sql
CLOSE tableCursor
DEALLOCATE tableCursor
select * from #TempTable
select sum(bytes) "Sum" from #TempTable
DROP TABLE #TempTable
#4 楼
试试这个:;WITH CTE as(select *,LEN(ISNULL(col1,''))+LEN(ISNULL(col2,'')) as row_len from yourtable)
select * from CTE where row_len > 8060
评论
您可以尝试使用msdn.microsoft.com/zh-cn/library/ms188917%28v=sql.105%29.aspx-SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'Database_Name'),OBJECT_ID(N'Table_Name') ,NULL,NULL,'DETAILED')并查找alloc_unit_type_desc为ROW_OVERFLOW_DATA的任何内容
MS SQL Server最多只能在一行中存储8060字节的数据,因此您的行大小始终为<= 8060.它将永远不会超过此值。
@AnandPhadke这不是完全正确:msdn.microsoft.com/en-us/library/ms186981%28SQL.90%29.aspx