我可以执行 T-SQL 查询来确定 SQL Server Express 实例的最大数据大小吗?

Posted

技术标签:

【中文标题】我可以执行 T-SQL 查询来确定 SQL Server Express 实例的最大数据大小吗?【英文标题】:Can I execute a T-SQL query to determine maximum data size for a SQL Server Express instance? 【发布时间】:2011-02-16 15:02:55 【问题描述】:

SQL Server Express 的原始版本具有 4GB 的固定数据库大小限制。在 2008 R2 中,这已增加到 10GB。

我们的原始代码执行SELECT SERVERPROPERTY ('edition'),然后查找字符串“Express”来识别快速版本。然后我们假设限制为 4GB。显然,当 2008 R2 推出时,这种情况就被打破了。我想避免使用“Express”或“Express R2”的存在来得出 4GB 或 10GB 的限制。如果/当微软推出带有一些任意新限制的“R3”版本时,这将失败。

是否有某种方法可以以编程方式确定(即通过执行 T-SQL 查询)当前大小限制?

【问题讨论】:

如果确实存在这样的东西,那将是令人惊讶的——它要么是更高版本的产品中毫无意义的功能,要么是他们必须添加到 Express 中的额外功能,非常价值不大。我会 a) 切换到 EngineEdition 属性,这样你就可以摆脱你的字符串比较,并且 b) 或者施加 4GB 的严格限制(你是如何使用这些信息的?),或者只写足够的代码来区分SQL2008 R2 之前和 SQL2008 R2 或更高版本,具有您现在知道的限制。 @Damien_The_Unbeliever - 虽然对于更高级的版本没有用处,但我们的应用程序要求用户安装自己的本地数据库(在 SQL Server Express 上,因为它是免费的!)。这是一个很好的功能,可以告诉他们空间不足。 【参考方案1】:

如果您在 SQL Server 2005 Express Edition 上恢复大于 4GB 的备份,您将收到以下错误:

CREATE DATABASE 或 ALTER DATABASE 失败,因为 产生的累积数据库大小将超过您的许可 每个数据库的限制为 4096 MB。

如果您在 SQL Server 2005 Express Edition 中有一个现有的数据库并且突然增长到超过 4GB,您将收到此错误:

由于文件组“YourFilegroup”中的磁盘空间不足,无法为数据库“YourDatabaseName”分配新页面。通过删除文件组中的对象、向文件组中添加其他文件或为文件组中的现有文件设置自动增长来创建必要的空间。

所以答案是否定的。数据库大小限制参数在 sqlservr.exe 中定义。 除非您可以重新编译原始代码,否则您无法通过 TSQL 获得它。

受@Kevin Ross 和@Damien_The_Unbeliever 建议的启发:

SELECT

CASE

WHEN SERVERPROPERTY ('EngineEdition') = 4 -- 4 = Express Edition

THEN

CASE

WHEN (SELECT max_size FROM sys.database_files WHERE file_id =1)=-1

THEN

CASE

WHEN CONVERT(REAL,CONVERT(VARCHAR(5),SUBSTRING(CONVERT(VARCHAR(5),SERVERPROPERTY('productversion')), 1, CHARINDEX('.', CONVERT(VARCHAR(5),SERVERPROPERTY('productversion')))-1))) < 10.5 -- Not SQL Server R2

THEN

'You have got '

+ CONVERT(VARCHAR(38), (SELECT 4096-size/128 FROM sys.database_files WHERE file_id =1))

+' Mb '

+'('

+ CONVERT(VARCHAR(38), CONVERT(int, 100*CONVERT(float, (SELECT 4096 - size/128 FROM sys.database_files WHERE file_id =1))

/
4096))

+ '%) available.'

+ ' You may increase your database size up to 4Gb.'

ELSE -- You have got SQL Server R2

'You have got '

+ CONVERT(VARCHAR(38), (SELECT 10240-size/128 FROM sys.database_files WHERE file_id =1))

+' Mb'

+'('

+ CONVERT(VARCHAR(38), CONVERT(int, 100*CONVERT(float, (SELECT 10240 - size/128 FROM sys.database_files WHERE file_id =1))

/
10240))

+ '%) available.'

+ ' You may increase your database size up to 10Gb.'

END

ELSE

CASE

WHEN CONVERT(REAL,CONVERT(VARCHAR(5),SUBSTRING(CONVERT(VARCHAR(5),SERVERPROPERTY('productversion')), 1, CHARINDEX('.', CONVERT(VARCHAR(5),SERVERPROPERTY('productversion')))-1))) < 10.5 -- Not SQL Server R2

THEN

'You have got '

+ CONVERT(VARCHAR(38), (SELECT max_size - size FROM sys.database_files WHERE file_id =1)/128)

+' Mb left out of '

+' Mb ('

+ CONVERT(VARCHAR(38), CONVERT(int, 100*CONVERT(float, (SELECT max_size - size FROM sys.database_files WHERE file_id =1))

/
CONVERT(float,(SELECT max_size FROM sys.database_files WHERE file_id =1))))

+ '%).'

+ ' You may increase your database size up to 4Gb.'

ELSE -- You have got SQL Server R2

'You have got '

+ CONVERT(VARCHAR(38), (SELECT max_size - size FROM sys.database_files WHERE file_id =1)/128)

+' Mb left out of '

+ CONVERT(VARCHAR(38), (SELECT max_size FROM sys.database_files WHERE file_id =1)/128)

+' Mb ('

+ CONVERT(VARCHAR(38), CONVERT(int, 100*CONVERT(float, (SELECT max_size - size FROM sys.database_files WHERE file_id =1))

/
CONVERT(float,(SELECT max_size FROM sys.database_files WHERE file_id =1))))

+ '%).'

+ ' You may increase your database size up to 10Gb.'

END

END

ELSE -- Congratulations! You have got something better than Express Edition!

CASE

WHEN (SELECT max_size FROM sys.database_files WHERE file_id =1)=-1

THEN

'Main file will grow until the disk is full.'

ELSE

'You have got '

+ CONVERT(VARCHAR(38), (SELECT max_size - size FROM sys.database_files WHERE file_id =1)/128)

+' Mb left out of '

+ CONVERT(VARCHAR(38), (SELECT max_size FROM sys.database_files WHERE file_id =1)/128)

+' Mb ('

+ CONVERT(VARCHAR(38), CONVERT(int, 100*CONVERT(float, (SELECT max_size - size FROM sys.database_files WHERE file_id =1))

/
CONVERT(float,(SELECT max_size FROM sys.database_files WHERE file_id =1))))

+ '%)'

END

END

AS
Database_Info 

显然我没有机会在 SQL Server 2005-2008-R2 上检查它。

【讨论】:

你能指出一篇文章,确认限制嵌入在 sqlservr.exe 中吗?请参阅我对这个问题的评论,解释为什么知道大小限制会很有用。 微软开发人员会知道的。由于许可的敏感问题,我个人认为您不会在互联网上找到任何东西。任何文本编辑器都会向您显示嵌入在 sqlservr.exe 中的上述错误消息。 感谢您的意见。您的 SQL 可能对其他人有用,但它并不能完全满足我的要求。我接受这个作为答案,因为正如您首先建议的那样,我最初想要的似乎是不可能的。谢谢【参考方案2】:

除了 2008R2 Express 之外,我没有其他任何东西可以测试这个,但是这样的东西可以吗?

SELECT 
case when SERVERPROPERTY ('EngineEdition')=4 THEN
     CASE WHEN convert(real,convert(varchar(5),SERVERPROPERTY('productversion'))) <10.5 THEN 
     '4Gb Limit' 
     ELSE '10Gb Limit' end
     else 'no limit' end as Size_Limit

首先检查它是否是 express 版本,如果不是,则返回“No Limit”,如果是 express,则检查版本号,如果小于 10.5(2008R2 之前),则返回 4Gb ,大于等于10.5则显示10Gb

【讨论】:

正如我在对问题的评论中所说,更强大的检查将使用 EngineEdition 属性而不是 Edition 属性 @Damien_The_Ungeliever 好声音,我已经更改了我的代码示例以摆脱字符串函数并将其替换为 EngineEdition 检查。 不幸的是,您的回答并没有真正提供我所要求的,即未来证明的解决方案(如果 MS 推出了具有更高限制的新 Express 版本)。帕维尔的另一个答案可能是正确的——也许我只能忍受这个限制。

以上是关于我可以执行 T-SQL 查询来确定 SQL Server Express 实例的最大数据大小吗?的主要内容,如果未能解决你的问题,请参考以下文章

T-SQL查询进阶—理解SQL Server中的锁

T-SQL 循环查询结果

确定与 T-SQL 中的同一集合连接的项目

T-SQL逻辑查询处理

我可以在 T-SQL 数据库中执行递归 SELECT

如何一次查询有限行中的 T-SQL 表