SQL Server 2012。本文底部的示例查询。
我正在尝试为上次备份给定数据库的时间创建一个简单的报告。
在 SSMS 中执行带有文本输出的示例查询时,该DB_NAME
列被格式化为数据的最大可能大小(DB2 中存在同样的问题,顺便说一句)。因此,我有一列包含的数据不超过 12 个字符,但它存储在 avarchar(128)
中,无论如何我都会得到 128 个字符的数据。RTRIM
对输出没有影响。
您是否知道一种优雅的方法可以使格式化的列长度成为实际数据的最大大小,而不是数据的最大潜在大小?
我想存在一个xp_sprintf()
函数,但我不熟悉它,而且它看起来不是非常健壮。
我试过这样投射它:
DECLARE @Servername_Length int;
SELECT @Servername_Length = LEN( CAST( SERVERPROPERTY('Servername') AS VARCHAR(MAX) ) ) ;
...
SELECT
CONVERT(CHAR(@Servername_Length), SERVERPROPERTY('Servername')) AS Server,
...
但是 SQL Server 不允许我在转换时使用定义中的@database_name_Length
变量varchar
。显然,SQL Server 在声明char
orvarchar
变量时需要一个文字数字。
我决定在一个字符串中构建语句并使用类似的东西sp_executesql
,或者用我需要的实际列长度构建一个临时表,这两者都比我希望去的麻烦多一点,只是为了不得到 100我的输出中的空格在 128 个字符的列上。
搜索了互联网并找到了bupkus。
也许我在寻找错误的东西,或者谷歌对我有意见。
似乎 SSMS 会将列格式化为允许的最大大小,即使实际数据要小得多。我希望有一种优雅的方式来“解决”这个问题,而无需跳过箍。我正在使用 SSMS 2012。
如果我转到结果到网格,然后转到 Excel 或类似的东西,尾随空格将被消除。不过,我希望基本上可以创建一份我通过电子邮件发送的报告。
示例查询
--------------------------------------------------------------------------
QUERY:
--------------------------------------------------------------------------
SELECT
CONVERT(CHAR(32), SERVERPROPERTY('Servername')) AS Server,
'''' + msdb.dbo.backupset.database_name + '''',
MAX(msdb.dbo.backupset.backup_finish_date) AS last_db_backup_date
FROM msdb.dbo.backupmediafamily
INNER JOIN msdb.dbo.backupset ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id
WHERE msdb..backupset.type = 'D'
GROUP BY
msdb.dbo.backupset.database_name
ORDER BY
msdb.dbo.backupset.database_name
CONVERT(VARCHAR(xx), ColumnName)
如果您希望列在文本输出视图中显得更短,则需要在所有列上使用。将您的查询转换为:
这将提供类似于以下内容的输出:
如果您希望能够在不修改 T-SQL 代码的情况下动态更改列宽,则需要使用动态 SQL:
在这里,我将所有列的宽度设置为 24,它看起来像:
如果您真的想发疯并让列自动调整大小,您可以这样做:
如果您想要快速简单的东西,并且可以接受所有列宽相同,请尝试SQLCMD.exe
-Y
选项:或者,由于这里的目标是将输出作为报告通过电子邮件发送,因此您可以使用sp_send_dbmail,如下所示:
笔记:
@ReportQuery
在示例中):SET NOCOUNT ON;
是必需的,否则“受影响的 X 行”会在最终</td></tr>
和</table>
标签之间打印,从而打乱表格的呈现CONVERT(NVARCHAR(x), ...
对可以隐式转换的类型的非字符串列的操作。对于 SQL Server 2012 之前的版本(何时CONCAT
引入),只需将CONVERT
s 和普通字符串连接到+
.@body
变量的内容之后(如果有的话)。@body_format = 'html'
是必需的,否则 HTML 标记的<
和>
将分别翻译为<
和>
,您将看到 HTML 标记(因为它们实际上不是HTML 标记)。@query_result_header = 0
<table>
是必需的,否则标签和初始之间会打印列标题行<tr><td>
,从而弄乱表格渲染。我编写了一个函数来获取特定长度的格式输出。这是我的解决方案。您可以在 SQL 查询中使用相同的: