4

在向表添加新列之前是否有一种干净的方法来确定表的行大小并且不超过 8060 字节限制?

例如,如果表行长度当前是 8055 字节,并且我想添加一个日期时间(8 字节),这将超过 8063 字节(不包括空映射)。

但是,如果我添加一个整数(4 个字节),这将给它 8059 个字节,这适合表大小(不包括空映射)。

我目前能够获取表的大小,但是我发现很难创建 SQL 函数来获取数据类型(int、datetime 等)的大小以及数据类型是否需要额外的字节来进行空映射。

是否有一个我可以使用/开发的函数接受两个变量:表名和数据类型:fnIsEnoughStorage('table1',int) 并从标量函数返回一个布尔值(是/否)。

如果为真,我将在确定测试后继续执行 ALTER TABLE 命令。

4

2 回答 2

7

此处的此查询将确定哪些表存在潜在危险,并且可能的最大行大小将超过可用的 8060 字节:

;WITH TableRowSizes AS
(
    SELECT 
        t.NAME 'TableName',
        COUNT(1) 'NumberOfColumns',
        SUM (c.max_length) 'MaxRowLength'
    FROM   
        sys.columns c
    INNER JOIN 
        sys.tables t ON c.object_id = t.object_id
    WHERE
        c.user_type_id NOT IN (98, 165, 167, 231)  -- sql_variant, varbinary, varchar, nvarchar
    GROUP BY 
        t.name
)
SELECT *
FROM TableRowSizes
WHERE MaxRowLength > 8060
ORDER BY MaxRowLength DESC

这并不意味着您的行实际上使用了超过 8060 个字节 - 它只是总结了每列可能的最大大小。

如果您想确定当前实际使用的大小,您可能可以通过检查DATALENGTH(colname)函数来做类似的事情(而不是使用来自 的理论最大值sys.columns

更新:根据 gbn 的响应在我的 CTE SELECT 中添加了 WHERE 子句 - 这些类型不应用于确定该行是否可能突破 8060 字节大小限制。

于 2011-09-02T04:50:22.447 回答
3

行可能会突破 8060 字节限制,因为 varchar/nvarchar 列可能会溢出

您会收到警告,但这是允许的。

如果您使用固定长度的 olumns 打破 8060 字节限制,那么您必须垂直分区(例如 1:1 表)。

请注意,您的新 int 列不会“放在最后”:磁盘结构定义明确,数据将被移动以适应新的固定长度字段一二

于 2011-09-02T04:49:19.560 回答