Tre*_*man 6 sql-server collation sql-server-2016
我的步骤:
> "C:\Program Files\Microsoft SQL Server\MSSQL13.STAGE\MSSQL\Binn\sqlservr.exe" -m -T4022 -T3659 -s"STAGE" -q"SQL_Latin1_General_CP1_CI_AS"
运行查询
Select i.name, c.collation_name,i.internal_type,i.internal_type_desc
from sys.columns c inner join sys.internal_tables i on c.object_id=i.object_id
WHERE c.collation_name <> 'SQL_Latin1_General_CP1_CI_AS'
AND object_name(c.object_id) NOT LIKE 'sys%'
AND object_name(c.object_id) NOT LIKE 'queue%'
AND object_name(c.object_id) NOT LIKE 'file%'
AND object_name(c.object_id) NOT LIKE 'spt%'
AND object_name(c.object_id) NOT LIKE 'MSrep%'
Run Code Online (Sandbox Code Playgroud)
将返回带有旧排序规则的内部表。
name collation_name internal_type internal_type_desc
sqlagent_jobs SQL_Latin1_General_CP850_CI_AS 220 CONTAINED_FEATURES
Run Code Online (Sandbox Code Playgroud)测试 2:
当实例排序规则设置为 SQL_Latin1_General_CP850_CI_AS 时,在 2016 年创建新数据库。
新的数据库排序规则具有 SQL_Latin1_General_CP850_CI_AS。
运行此查询 where collation = SQL_Latin1_General_CP1_CI_AS
Select i.name, c.collation_name,i.internal_type,i.internal_type_desc
from sys.columns c inner join sys.internal_tables i on c.object_id=i.object_id
WHERE c.collation_name = 'SQL_Latin1_General_CP1_CI_AS'
AND object_name(c.object_id) NOT LIKE 'sys%'
AND object_name(c.object_id) NOT LIKE 'queue%'
AND object_name(c.object_id) NOT LIKE 'file%'
AND object_name(c.object_id) NOT LIKE 'spt%'
AND object_name(c.object_id) NOT LIKE 'MSrep%'
Run Code Online (Sandbox Code Playgroud)
这将返回与当前排序规则不匹配的结果。名称 collation_name internal_type internal_type_desc sqlagent_jobs SQL_Latin1_General_CP1_CI_AS 220 CONTAINED_FEATURES
我不认为应用程序会受到这个 internal_table 的影响。但仍然奇怪的是 internal_table 排序规则不匹配,在创建和将实例转换为新排序规则之后。
如果我执行相同的过程,但这次是在 2012 Staging 实例上。
"C:\Program Files\Microsoft SQL Server\MSSQL11.STAGE12\MSSQL\Binn\sqlservr.exe" -m -T4022 -T3659 -s"STAGE" -q"SQL_Latin1_General_CP1_CI_AS"
运行查询
Select i.name, c.collation_name,i.internal_type,i.internal_type_desc
from sys.columns c inner join sys.internal_tables i on c.object_id=i.object_id
WHERE c.collation_name <> 'SQL_Latin1_General_CP1_CI_AS'
AND object_name(c.object_id) NOT LIKE 'sys%'
AND object_name(c.object_id) NOT LIKE 'queue%'
AND object_name(c.object_id) NOT LIKE 'file%'
AND object_name(c.object_id) NOT LIKE 'spt%'
AND object_name(c.object_id) NOT LIKE 'MSrep%'
Run Code Online (Sandbox Code Playgroud)没有任何回报,因为我在 2012 年对其进行了转换。
如果有人可以解释发生了什么?这是一个错误吗?任何人都知道如何修复内部表格整理?
我已经看了看内部表列的排序规则在大多数我的测试情况下,他们是所有无论是SQL_Latin1_General_CP1_CI_AS
或Latin1_General_BIN
。有些实例是 SQL Server Express LocalDB,它们始终SQL_Latin1_General_CP1_CI_AS
处于实例级别(不幸的是),但我Korean_100_CS_AS_KS_WS_SC
在实例级别安装了 2017 Express,在实例级别安装了 2019 CTP 2.3 UTF8_BIN2
。我将数据库恢复到 2019 年的实例(来自 CTP 2.2,而不是像您的情况那样的早期版本),French_100_CI_AS_SC_UTF8
并带有 和 的排序规则French_100_CI_AS
。
我目前正在使用另一个SQL Server 2017年Express实例Estonian_100_CS_AS_SC
在实例和DB水平,并使用该实例已更改-q
选项很多说选项测试时间。它甚至有一个 Contained DB (containment_type = PARTIAL
),并且内部表中的所有列都是SQL_Latin1_General_CP1_CI_AS
或Latin1_General_BIN
,没有例外。
我不会担心这些列。它们显然都是希望保留其特定排序规则的 MS Shipped 对象。并且您永远不会有时间 100% 的排序规则是您为实例设置的。用于元数据的排序规则有自己的静态排序规则。排序规则来自系统目录视图中的表达式和具有显式排序规则集的函数等。您可以使用以下查询查看所有不是您将实例和数据库设置为的排序规则:
SELECT OBJECT_SCHEMA_NAME(col.[object_id]) AS [SchemaName],
ISNULL(obj.[name], OBJECT_NAME(col.[object_id])) AS [ObjectName],
col.[name] AS [ColumnName],
col.[collation_name] AS [Collation],
obj.[type_desc],
ISNULL(obj.[is_ms_shipped],
OBJECTPROPERTY(col.[object_id], 'IsMSShipped')) AS [IsMSShipped],
col.[object_id]
FROM sys.[all_columns] col
LEFT JOIN sys.[all_objects] obj
ON obj.[object_id] = col.[object_id]
WHERE col.[collation_name] IS NOT NULL
AND col.[collation_name] NOT IN (
CONVERT([sysname], SERVERPROPERTY('collation')),
CONVERT([sysname], DATABASEPROPERTYEX(DB_NAME(), 'collation')))
ORDER BY [SchemaName], [ObjectName], [ColumnName];
Run Code Online (Sandbox Code Playgroud)
有些对象不在 中sys.all_objects
,例如sys.pdw_nodes_partitions
,这在object_id
任何地方都是相同的(跨实例甚至 SQL Server 版本,但在 SQL Server 2012 中不存在):
SELECT OBJECT_SCHEMA_NAME(-1046288262) AS [SchemaName],
OBJECT_NAME(-1046288262) AS [ObjectName],
OBJECTPROPERTY(-1046288262, 'IsExecuted') AS [IsExecuted],
OBJECTPROPERTY(-1046288262, 'IsView') AS [IsView],
OBJECTPROPERTY(-1046288262, 'IsMSShipped') AS [IsMSShipped];
Run Code Online (Sandbox Code Playgroud)
不过,我不确定如何解释您在测试 1 中看到的结果。您说:
将返回带有旧排序规则的内部表。
根据我在本答案顶部的所有这些版本等中发现的所有内容,应该永远不可能将列输入sqlagent_jobs
为SQL_Latin1_General_CP1_CI_AS
. 在创建这些内部表时,这可能是数据库升级过程的侥幸。SQL Server 2012 中不存在“CONTAINED_FEATURES”表,因此当您还原到 SQL Server 2016 时,必须在此时创建它们。您的 2016 年整理是SQL_Latin1_General_CP850_CI_AS
,这是我目前看到的唯一联系。
我能够重现这个!!我从 SQL Server 2012 LocalDB 备份了一个数据库,该数据库的排序规则为Latin1_General_100_CS_AS_KS_SC
. 然后我将其恢复到 SQL Server 2019(实例级排序规则为UTF8_BIN2
)。检查内部表,我看到 3 个queue_messages_*
表和filestream_tombstone_2073058421
表(所有这些都存在于 SQL Server 2012 中)仍然有Latin1_General_BIN
. 但是,sqlagent_*
表和plan_persist_*
表(在 SQL Server 2012 中都不存在),都有一个排序规则Latin1_General_100_CS_AS_KS_SC
(与恢复的数据库相同)。
然后,我从 SQL Server 2014 LocalDB 备份了一个数据库,该数据库的排序规则为Latin1_General_100_CS_AS_KS_WS_SC
. 然后我将其恢复到 SQL Server 2019(实例级排序规则为UTF8_BIN2
)。检查内部表,我看到 3 个queue_messages_*
表和filestream_tombstone_2073058421
表(所有这些都存在于 SQL Server 2012 中)仍然有Latin1_General_BIN
. 但是,这一次的sqlagent_*
表(确实存在于 SQL Server 2014 中)的排序规则都是SQL_Latin1_General_CP1_CI_AS
. 这些plan_persist_*
表(SQL Server 2014 中仅存在 6 个中的 2 个),所有表的排序规则均为Latin1_General_100_CS_AS_KS_WS_SC
(同样,与恢复的数据库相同)。
我将从 SQL Server 2012 恢复的 DB 的兼容模式更改为“SQL Server 2019 (150)”,但这并没有解决整理问题。
这显然是数据库升级过程的一个问题,与sqlservr.exe -q
更改服务器上所有排序规则的方法无关(官方没有记录且不受支持,但我确实在此处记录了它:更改实例的排序规则,数据库,以及所有用户数据库中的所有列:可能出现什么问题?)。我已经通过几乎没有功能、甚至低于 2008-2010 年标准的报告站点 UserVoice 向 Microsoft 报告了这个错误:将数据库恢复到较新版本的 SQL Server 将创建缺失的内部表,并且排序不正确。
关于测试 2:
排序规则 = SQL_Latin1_General_CP1_CI_AS
是的,预计这些内部表将使用旧的、应该已经删除的排序规则。
关于测试 3:
没有任何回报,因为我在 2012 年对其进行了转换。
不对。没有任何回报,因为:
AND object_name(c.object_id) NOT LIKE 'queue%'
,而那些使用Latin1_General_BIN
.WHERE c.collation_name <> 'SQL_Latin1_General_CP1_CI_AS'
。