Luego de tanto luchar hemos hallado la contestación de esta dificultad que ciertos de nuestros lectores de nuestro sitio web tienen. Si tienes algún detalle que compartir no dudes en dejar tu comentario.
Solución:
Necesitas usar CONVERT(VARCHAR(xx), ColumnName)
en todas las columnas si desea que la columna aparezca más corta en la vista de salida de texto.
Convierta su consulta en algo como:
SELECT [Server] = CONVERT(VARCHAR(30), SERVERPROPERTY('Servername'))
, DatabaseName = CONVERT(VARCHAR(30), '''' + bs.database_name + '''')
, LastDatabaseBackupDate = CONVERT(VARCHAR(30), MAX(bs.backup_finish_date))
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bmf.media_set_id = bs.media_set_id
WHERE bs.[type] = 'D'
GROUP BY bs.database_name
ORDER BY bs.database_name;
Esto dará una salida similar a:
Server DatabaseName LastDatabaseBackupDate
------------------------------ ------------------------------ ------------------------------
[ServerName] 'A' Sep 25 2015 11:32AM
[ServerName] 'B' Apr 21 2015 12:09PM
[ServerName] 'C' Feb 24 2015 9:16PM
[ServerName] 'D' Oct 8 2014 11:02AM
[ServerName] 'E' May 14 2014 6:27PM
(5 row(s) affected)
Si desea poder cambiar dinámicamente el ancho de las columnas sin modificar el código T-SQL, deberá usar SQL dinámico:
DECLARE @ColumnWidth VARCHAR(4);
DECLARE @Cmd NVARCHAR(MAX);
SET @ColumnWidth = '24';
SET @Cmd = '
SELECT [Server] = CONVERT(VARCHAR(' + @ColumnWidth + '), SERVERPROPERTY(''Servername''))
, DatabaseName = CONVERT(VARCHAR(' + @ColumnWidth + '), '''''''' + bs.database_name + '''''''')
, LastDatabaseBackupDate = CONVERT(VARCHAR(' + @ColumnWidth + '), MAX(bs.backup_finish_date))
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bmf.media_set_id = bs.media_set_id
WHERE bs.[type] = ''D''
GROUP BY bs.database_name
ORDER BY bs.database_name;
';
EXEC (@cmd);
Aquí, configuré el ancho en 24 para todas las columnas, y se ve así:
Server DatabaseName LastDatabaseBackupDate
------------------------ ------------------------ ------------------------
SERVERNAME 'A' Sep 25 2015 11:32AM
SERVERNAME 'A' Apr 21 2015 12:09PM
SERVERNAME 'A' Feb 24 2015 9:16PM
SERVERNAME 'A' Oct 8 2014 11:02AM
SERVERNAME 'A' May 14 2014 6:27PM
(5 row(s) affected)
Si realmente quiere volverse loco y que las columnas se ajusten automáticamente a sí mismas, debe hacer esto:
DECLARE @ColumnWidthServer VARCHAR(4);
DECLARE @ColumnWidthDatabase VARCHAR(4);
DECLARE @ColumnWidthLastBackup VARCHAR(4);
DECLARE @Cmd NVARCHAR(MAX);
SELECT @ColumnWidthServer = 1 + LEN(CONVERT(VARCHAR(128), SERVERPROPERTY('Servername')))
, @ColumnWidthDatabase = 1 + MAX(LEN('''' + bs.database_name + ''''))
, @ColumnWidthLastBackup = 1 + MAX(LEN(CONVERT(VARCHAR(128), bs.backup_finish_date)))
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bmf.media_set_id = bs.media_set_id
WHERE bs.[type] = 'D';
SET @Cmd = '
SELECT [Server] = CONVERT(VARCHAR(' + @ColumnWidthServer + '), SERVERPROPERTY(''Servername''))
, DatabaseName = CONVERT(VARCHAR(' + @ColumnWidthDatabase + '), '''''''' + bs.database_name + '''''''')
, LastDatabaseBackupDate = CONVERT(VARCHAR(' + @ColumnWidthLastBackup + '), MAX(bs.backup_finish_date))
FROM msdb.dbo.backupmediafamily bmf
INNER JOIN msdb.dbo.backupset bs ON bmf.media_set_id = bs.media_set_id
WHERE bs.[type] = ''D''
GROUP BY bs.database_name
ORDER BY bs.database_name;
';
EXEC (@cmd);
Si quieres algo rápido y fácil, y puede aceptar que todos los anchos de columna sean iguales, luego intente el -Y
opción de SQLCMD.exe:
C:>SQLCMD -Y 3 -Q "SELECT name, name, name from sys.objects;"
nam nam nam
--- --- ---
sys sys sys
pla pla pla
spt spt spt
fai fai fai
MSr MSr MSr
sp_ sp_ sp_
O, dado que el objetivo aquí es enviar el resultado por correo electrónico como un informe, puede usar sp_send_dbmail de la siguiente manera:
DECLARE @ReportQuery NVARCHAR(MAX) = N'SET NOCOUNT ON;
PRINT ''
Server DatabaseName LastBackupDate '';
SELECT CONCAT(
'''',
CONVERT(sysname, SERVERPROPERTY(''Servername'')),
'' '',
N'''''''' + bset.[database_name] + N'''''''',
'' '',
MAX(bset.backup_finish_date),
'' '')
FROM msdb.dbo.backupmediafamily bfam
INNER JOIN msdb.dbo.backupset bset
ON bset.media_set_id = bfam.media_set_id
WHERE bset.[type] = ''D''
GROUP BY bset.[database_name]
ORDER BY bset.[database_name];
PRINT ''
'';
';
EXEC msdb.dbo.sp_send_dbmail
@profile_name = N'your_Profile_name',
@recipients = N'email_address(es)',
-- @copy_recipients = N'copy_recipient [ ; ...n ]',
-- @blind_copy_recipients = N'blind_copy_recipient [ ; ...n ]',
@subject = N'Reporty Stuffs', -- NVARCHAR(255)
@body = N'Here is the report you asked for...',
@body_format = 'html', -- HTML or TEXT (default)
-- @importance = 'importance', -- Low, Normal (default), or High
-- @sensitivity = 'sensitivity', -- Normal (default), Personal, Private, Confidential
@query = @ReportQuery,
-- @execute_query_database = N'DB name',
@query_result_header = 0; -- 0 or 1 (default)
Notas:
- En la Consulta de informe (
@ReportQuery
en el ejemplo):SET NOCOUNT ON;
es obligatorio, de lo contrario, se imprime “X filas afectadas” entre los- CONCAT facilita la construcción de la fila de la tabla HTML porque puede omitir
CONVERT(NVARCHAR(x), ...
para nostring columnas de tipos que se pueden convertir implícitamente. Para versiones anteriores a SQL Server 2012 (cuandoCONCAT
fue introducido), simplemente haga elCONVERT
sy normal string concatenación con+
.
- La salida de la consulta vendrá después del contenido de la
@body
variable (si hay alguna). @body_format = 'html'
se requiere, de lo contrario el<
y>
de las etiquetas HTML se traducirán a<
y>
, respectivamente, y verá las etiquetas HTML (ya que en realidad no ser Etiquetas HTML).@query_result_header = 0
es necesario, de lo contrario se imprime una línea de encabezado de columna entre
etiqueta y la inicial
, arruinando la representación de la tabla. Si sostienes algún recelo o forma de renovar nuestro tutorial puedes añadir una anotación y con mucho placer lo observaremos.
¡Haz clic para puntuar esta entrada!(Votos: 0 Promedio: 0)Utiliza Nuestro Buscador