Estoy intentando ejecutar una UNPIVOT
en varias columnas contenidas en sys.databases
varias versiones de SQL Server, que van desde 2005 hasta 2012.
El UNPIVOT
está fallando con el siguiente mensaje de error:
Mensaje 8167, Nivel 16, Estado 1, Línea 48
El tipo de columna "CompatibilityLevel" entra en conflicto con el tipo de otras columnas especificadas en la lista UNPIVOT.
El T-SQL:
DECLARE @dbname SYSNAME;
SET @dbname = DB_NAME();
SELECT [Database] = unpvt.DatabaseName
, [Configuration Item] = unpvt.OptionName
, [Configuration Value] = unpvt.OptionValue
FROM (
SELECT
DatabaseName = name
, RecoveryModel = CONVERT(VARCHAR(50), d.recovery_model_desc)
, CompatibilityLevel = CONVERT(VARCHAR(50), CASE d.[compatibility_level] WHEN 70 THEN 'SQL Server 7' WHEN 80 THEN 'SQL Server 2000' WHEN 90 THEN 'SQL Server 2005' WHEN 100 THEN 'SQL Server 2008' WHEN 110 THEN 'SQL Server 2012' WHEN 120 THEN 'SQL Server 2014' ELSE 'UNKNOWN' END)
, AutoClose = CONVERT(VARCHAR(50), CASE d.is_auto_close_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoCreateStatistics = CONVERT(VARCHAR(50), CASE d.is_auto_create_stats_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoShrink = CONVERT(VARCHAR(50), CASE d.is_auto_shrink_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoUpdateStatistics = CONVERT(VARCHAR(50), CASE d.is_auto_update_stats_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoUpdateStatisticsAsynch = CONVERT(VARCHAR(50), CASE d.is_auto_update_stats_async_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, CloseCursorOnCommit = CONVERT(VARCHAR(50), CASE d.is_cursor_close_on_commit_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DefaultCursor = CONVERT(VARCHAR(50), CASE d.is_local_cursor_default WHEN 1 THEN 'LOCAL' ELSE 'GLOBAL' END)
, ANSINULL_Default = CONVERT(VARCHAR(50), CASE d.is_ansi_null_default_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSINULLS_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_nulls_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSIPadding_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_padding_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSIWarnings_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_warnings_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ArithmeticAbort_Enabled = CONVERT(VARCHAR(50), CASE d.is_arithabort_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ConcatNullYieldsNull = CONVERT(VARCHAR(50), CASE d.is_concat_null_yields_null_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, CrossDBOwnerChain = CONVERT(VARCHAR(50), CASE d.is_db_chaining_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DateCorrelationOptimized = CONVERT(VARCHAR(50), CASE d.is_date_correlation_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, NumericRoundAbort = CONVERT(VARCHAR(50), CASE d.is_numeric_roundabort_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, [Parameterization] = CONVERT(VARCHAR(50), CASE d.is_parameterization_forced WHEN 0 THEN 'SIMPLE' ELSE 'FORCED' END)
, QuotedIdentifiers_Enabled = CONVERT(VARCHAR(50), CASE d.is_quoted_identifier_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, RecursiveTriggers_Enabled = CONVERT(VARCHAR(50), CASE d.is_recursive_triggers_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, [TrustWorthy] = CONVERT(VARCHAR(50), CASE d.is_trustworthy_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, VARDECIMAL_Storage = CONVERT(VARCHAR(50), 'TRUE')
, PageVerify = CONVERT(VARCHAR(50), page_verify_option_desc )
, BrokerEnabled = CONVERT(VARCHAR(50), CASE d.is_broker_enabled WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DatabaseReadOnly = CONVERT(VARCHAR(50), CASE d.is_read_only WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, EncryptionEnabled = CONVERT(VARCHAR(50), CASE d.is_encrypted WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, RestrictedAccess = CONVERT(VARCHAR(50), user_access_desc)
, Collation = CONVERT(VARCHAR(50), d.collation_name)
FROM sys.databases d
WHERE name = @dbname
OR @dbname IS NULL
) src
UNPIVOT
(
OptionValue FOR OptionName IN
(
RecoveryModel
, CompatibilityLevel
, AutoClose
, AutoCreateStatistics
, AutoShrink
, AutoUpdateStatistics
, AutoUpdateStatisticsAsynch
, CloseCursorOnCommit
, DefaultCursor
, ANSINULL_Default
, ANSINULLS_Enabled
, ANSIPadding_Enabled
, ANSIWarnings_Enabled
, ArithmeticAbort_Enabled
, ConcatNullYieldsNull
, CrossDBOwnerChain
, DateCorrelationOptimized
, NumericRoundAbort
, [Parameterization]
, QuotedIdentifiers_Enabled
, RecursiveTriggers_Enabled
, [TrustWorthy]
, VARDECIMAL_Storage
, PageVerify
, BrokerEnabled
, DatabaseReadOnly
, EncryptionEnabled
, RestrictedAccess
, Collation
)
) AS unpvt;
Esto está diseñado para proporcionar una lista bien formateada de opciones de base de datos para la base de datos dada, similar a:
+----------+----------------------------+----------------------------+
| Database | Configuration Item | Value in Use |
+----------+----------------------------+----------------------------+
| master | RecoveryModel | SIMPLE |
| master | CompatibilityLevel | SQL Server 2008 |
| master | AutoClose | FALSE |
| master | AutoCreateStatistics | TRUE |
| master | AutoShrink | FALSE |
| master | AutoUpdateStatistics | TRUE |
| master | AutoUpdateStatisticsAsynch | FALSE |
| master | CloseCursorOnCommit | FALSE |
| master | DefaultCursor | GLOBAL |
| master | ANSINULL_Default | FALSE |
| master | ANSINULLS_Enabled | FALSE |
| master | ANSIPadding_Enabled | FALSE |
| master | ANSIWarnings_Enabled | FALSE |
| master | ArithmeticAbort_Enabled | FALSE |
| master | ConcatNullYieldsNull | FALSE |
| master | CrossDBOwnerChain | TRUE |
| master | DateCorrelationOptimized | FALSE |
| master | NumericRoundAbort | FALSE |
| master | Parameterization | SIMPLE |
| master | QuotedIdentifiers_Enabled | FALSE |
| master | RecursiveTriggers_Enabled | FALSE |
| master | TrustWorthy | TRUE |
| master | VARDECIMAL_Storage | TRUE |
| master | PageVerify | CHECKSUM |
| master | BrokerEnabled | FALSE |
| master | DatabaseReadOnly | FALSE |
| master | EncryptionEnabled | FALSE |
| master | RestrictedAccess | MULTI_USER |
| master | Collation | Latin1_General_CI_AS_KS_WS |
+----------+----------------------------+----------------------------+
Cuando ejecuto esto en un servidor con Latin1_General_CI_AS_KS_WS
intercalación, la declaración tiene éxito. Si modifico el T-SQL para que ciertos campos tengan una COLLATE
cláusula, se ejecutará en servidores que tengan otras intercalaciones.
El código que funciona en servidores con intercalaciones distintas Latin1_General_CI_AS_KS_WS
es:
DECLARE @dbname SYSNAME;
SET @dbname = DB_NAME();
SELECT [Database] = unpvt.DatabaseName
, [Configuration Item] = unpvt.OptionName
, [Configuration Value] = unpvt.OptionValue
FROM (
SELECT
DatabaseName = name
, RecoveryModel = CONVERT(VARCHAR(50), d.recovery_model_desc) COLLATE SQL_Latin1_General_CP1_CI_AS
, CompatibilityLevel = CONVERT(VARCHAR(50), CASE d.[compatibility_level] WHEN 70 THEN 'SQL Server 7' WHEN 80 THEN 'SQL Server 2000' WHEN 90 THEN 'SQL Server 2005' WHEN 100 THEN 'SQL Server 2008' WHEN 110 THEN 'SQL Server 2012' WHEN 120 THEN 'SQL Server 2014' ELSE 'UNKNOWN' END)
, AutoClose = CONVERT(VARCHAR(50), CASE d.is_auto_close_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoCreateStatistics = CONVERT(VARCHAR(50), CASE d.is_auto_create_stats_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoShrink = CONVERT(VARCHAR(50), CASE d.is_auto_shrink_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoUpdateStatistics = CONVERT(VARCHAR(50), CASE d.is_auto_update_stats_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, AutoUpdateStatisticsAsynch = CONVERT(VARCHAR(50), CASE d.is_auto_update_stats_async_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, CloseCursorOnCommit = CONVERT(VARCHAR(50), CASE d.is_cursor_close_on_commit_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DefaultCursor = CONVERT(VARCHAR(50), CASE d.is_local_cursor_default WHEN 1 THEN 'LOCAL' ELSE 'GLOBAL' END)
, ANSINULL_Default = CONVERT(VARCHAR(50), CASE d.is_ansi_null_default_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSINULLS_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_nulls_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSIPadding_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_padding_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ANSIWarnings_Enabled = CONVERT(VARCHAR(50), CASE d.is_ansi_warnings_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ArithmeticAbort_Enabled = CONVERT(VARCHAR(50), CASE d.is_arithabort_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, ConcatNullYieldsNull = CONVERT(VARCHAR(50), CASE d.is_concat_null_yields_null_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, CrossDBOwnerChain = CONVERT(VARCHAR(50), CASE d.is_db_chaining_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DateCorrelationOptimized = CONVERT(VARCHAR(50), CASE d.is_date_correlation_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, NumericRoundAbort = CONVERT(VARCHAR(50), CASE d.is_numeric_roundabort_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, [Parameterization] = CONVERT(VARCHAR(50), CASE d.is_parameterization_forced WHEN 0 THEN 'SIMPLE' ELSE 'FORCED' END)
, QuotedIdentifiers_Enabled = CONVERT(VARCHAR(50), CASE d.is_quoted_identifier_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, RecursiveTriggers_Enabled = CONVERT(VARCHAR(50), CASE d.is_recursive_triggers_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, [TrustWorthy] = CONVERT(VARCHAR(50), CASE d.is_trustworthy_on WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, VARDECIMAL_Storage = CONVERT(VARCHAR(50), 'TRUE')
, PageVerify = CONVERT(VARCHAR(50), page_verify_option_desc ) COLLATE SQL_Latin1_General_CP1_CI_AS
, BrokerEnabled = CONVERT(VARCHAR(50), CASE d.is_broker_enabled WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, DatabaseReadOnly = CONVERT(VARCHAR(50), CASE d.is_read_only WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, EncryptionEnabled = CONVERT(VARCHAR(50), CASE d.is_encrypted WHEN 0 THEN 'FALSE' ELSE 'TRUE' END)
, RestrictedAccess = CONVERT(VARCHAR(50), user_access_desc) COLLATE SQL_Latin1_General_CP1_CI_AS
, Collation = CONVERT(VARCHAR(50), d.collation_name)
FROM sys.databases d
WHERE name = @dbname
OR @dbname IS NULL
) src
UNPIVOT
(
OptionValue FOR OptionName IN
(
RecoveryModel
, CompatibilityLevel
, AutoClose
, AutoCreateStatistics
, AutoShrink
, AutoUpdateStatistics
, AutoUpdateStatisticsAsynch
, CloseCursorOnCommit
, DefaultCursor
, ANSINULL_Default
, ANSINULLS_Enabled
, ANSIPadding_Enabled
, ANSIWarnings_Enabled
, ArithmeticAbort_Enabled
, ConcatNullYieldsNull
, CrossDBOwnerChain
, DateCorrelationOptimized
, NumericRoundAbort
, [Parameterization]
, QuotedIdentifiers_Enabled
, RecursiveTriggers_Enabled
, [TrustWorthy]
, VARDECIMAL_Storage
, PageVerify
, BrokerEnabled
, DatabaseReadOnly
, EncryptionEnabled
, RestrictedAccess
, Collation
)
) AS unpvt;
El comportamiento observado es que los siguientes campos no observan ni la intercalación del servidor ni la intercalación de la base de datos; que están siempre presentan en Latin1_General_CI_AS_KS_WS
el cotejo.
En SQL Server 2012, podemos usar sys.sp_describe_first_result_set
para obtener fácilmente metadatos sobre las columnas devueltas de una consulta en particular. Usé lo siguiente para determinar la falta de coincidencia de colación:
DECLARE @cmd NVARCHAR(MAX);
SET @cmd = '
SELECT
DatabaseName = CONVERT(VARCHAR(50), d.name)
, RecoveryModel = CONVERT(VARCHAR(50), d.recovery_model_desc)
, Collation = CONVERT(VARCHAR(50), d.collation_name)
FROM sys.databases d
WHERE name = DB_NAME();
';
EXEC sp_describe_first_result_set @command = @cmd;
Los resultados:
¿Por qué la clasificación de estas columnas está establecida estáticamente?
fuente