标签: collation

更改生产环境中 SQL 数据库的排序规则以最大程度地减少停机时间

我们有一个场景,我们希望将生产数据库(包括列)的排序规则从 SQL_Scandinavian_Pref_CP850_CI_AS 更改为 Finnish_Swedish_CI_AS。我们已经开发了脚本来做到这一点。但是在超过 100GB 的大型数据库中执行此脚本将需要相当长的时间,而且我们不能承受很长时间的停机时间。因此,我们决定使用以下策略来减少停机时间:

  1. 我们将设置事务复制,我们将使用数据库备份方法初始化订阅者。
  2. 发布者数据库将与应用程序一起使用,其事务将通过事务复制传递到订阅者数据库。
  3. 我们将在订阅者端执行排序规则更改脚本,当 SQL Server 对发布者和订阅者数据库相同时,它确实允许我们执行此脚本。我们最近在 SQL Server 2019 中发现了这一点。
  4. 现在,痛点是,当 varchar、char 列的数据包含诸如“åÅääÄöÖ”之类的特殊字符时,它无法正确复制。在订阅者方面,我们收到了像“†„Ž”™“这样的奇怪字符

您能否建议我们如何解决此错误或任何替代架构,以在更改数据库排序规则(包括列)时最大限度地减少生产停机时间?

此外,我的排序规则更改脚本正在订阅者数据库上执行以下任务以更改其排序规则:

  1. 删除外键约束
  2. 删除包括主键在内的索引
  3. 删除检查和默认约束
  4. 删除用户统计
  5. 删除视图、计算列、SP 以解决对象绑定错误
  6. 执行上述步骤后,表已准备好进行整理更改。因此,脚本将一一更改每个表的列的排序规则。
  7. 成功执行第 6 步后,重新创建上面列出的约束。

sql-server collation transactional-replication

8
推荐指数
1
解决办法
440
查看次数

更改为 utf8_general_ci 时 DateTime 的默认值无效

我正在尝试运行一个脚本来修改数据库,这个查询

ALTER TABLE cmContentVersion CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
Run Code Online (Sandbox Code Playgroud)

给出这个错误

ERROR 1067 (42000) at line 68: Invalid default value for 'modifiedDateTime'
Warning (Code 1264): Out of range value for column 'modifiedDateTime' at row 1
Error (Code 1067): Invalid default value for 'modifiedDateTime'
Run Code Online (Sandbox Code Playgroud)

该列modifiedDateTime被定义为

`modifiedDateTime` datetime NOT NULL default '0000-00-00 00:00:00',
Run Code Online (Sandbox Code Playgroud)

问题:在使用 utf8_general_ci 时,是否有可以替换的有效“无效”默认值0000-00-00 00:00:00。或者我是否必须告诉开发人员停止依赖他们代码中的“无效日期”?

mysql collation

7
推荐指数
1
解决办法
2万
查看次数

sql_slovak_cp1250_ci_as 与 Slovak_CI_AS

有人可以向我解释 collat​​ionsql_slovak_cp1250_ci_as与collat​​ion 之间的区别Slovak_CI_AS吗?

我有一个 db 设置为sql_slovak_cp1250_ci_as并且共享主机仅支持Slovak_CI_AS. 应该不会有问题吧?

非常感谢。

sql-server collation sql-server-2012

7
推荐指数
1
解决办法
4284
查看次数

无法从 NVARCHAR 列中删除字符 0x0000

所以,我知道所有关于 Replace 函数和 char(0) 的错误。

我有一列 ( NVARCHAR(128)) 有一些NCHAR(0x0000)来自错误导入的字符。

我正在使用 SQL Server 2008 R2。

该列的排序规则是:SQL_Latin1_General_CP1_CI_AS

我已经尝试了所有可能在网上找到的东西,但没有任何东西可以从列中取出臭气熏天的 char(0) 字符。

这是我的最新尝试,结果是 BAFFLING(sql server 中的错误?)。

我有一个循环遍历每个字符并用特定字符替换 0x0000 的函数。

ALTER FUNCTION dbo.ReplaceCharZero
(
  @testString NVARCHAR(MAX),
  @charToReplaceWith NCHAR(1) = ' '
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    DECLARE
        @i INT = 1 ,
        @fixedString NVARCHAR(MAX) = ''
    WHILE @i <= LEN(@testString)
        BEGIN
            IF SUBSTRING(@testString, @i, 1) = CHAR(0x00)
                BEGIN
                    --PRINT 'Found' + CAST(@i AS VARCHAR)
                    SET @fixedString = @fixedString + @charToReplaceWith …
Run Code Online (Sandbox Code Playgroud)

sql-server collation sql-server-2008-r2 unicode

7
推荐指数
2
解决办法
5808
查看次数

在表中存储日语字符

我正在使用 SQL Server 2008 R2 并且我想将日语字符存储在我的表的列之一中。

说我想存储日语名字,我怎样才能做到这一点?有没有简单的方法?

sql-server collation unicode

7
推荐指数
1
解决办法
3万
查看次数

变量中的排序规则

在遇到了 ISO-8859-1 的许多问题并阅读了很多有关排序规则的内容之后,我终于明白我需要使用 charset UTF8 collate utf8_unicode_ci。因此,我使用这些更改配置了整个应用程序,并且似乎工作顺利,直到我需要执行手动查询

SET @id := '10000016';
SET @invoice := (SELECT invoice FROM WAREHOUSE WHERE invoice_id = @id);
Run Code Online (Sandbox Code Playgroud)

此查询在 MySQL Workbench 中给我错误并带有排序规则消息:

Error Code: 1267. Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
Run Code Online (Sandbox Code Playgroud)

我可以使用 修复它SET @id := '10000016' collate utf8_unicode_ci;,但这对我来说似乎很奇怪(至少可以说)。我确信缺少一些步骤。

也许我需要在 my.cnf 中调整一些东西?

其他信息

SELECT @@character_set_client; # utf8
SELECT @@character_set_results; # utf8
SELECT @@collation_connection; # utf8_general_ci
Run Code Online (Sandbox Code Playgroud)

感谢您的时间

mysql collation

7
推荐指数
0
解决办法
5545
查看次数

SQL Server:更改现有数据库的排序规则是否安全?

我是 SQL Server 的新手,不知道 T-SQL 可能不区分大小写的可能性。

我一直在通过拆分表和约束来规范化实体。我很害怕如果我现在更改排序规则,例如,如果“不区分大小写”的外键值指向具有不同大小写的 PK 值,那么其中一些约束可能无效。

如果我在数据库上运行这个查询(在基本数据库上测试):

ALTER DATABASE <db_name>
COLLATE SQL_Latin1_General_Cp1_CS_AS ;
GO
Run Code Online (Sandbox Code Playgroud)

如果违反某些约束会发生什么?

是否有任何其他原因我应该小心进行数据库范围的更改,例如更改排序规则?

sql-server collation sql-server-2012

7
推荐指数
1
解决办法
9996
查看次数

为什么两个相同的字符串长度不同但二进制值相同?

我试图从表中返回一组不同的部门名称 - 没什么特别的。但是,使用以下查询时会显示重复项:

  select distinct department_name
    from dbo.departments;
Run Code Online (Sandbox Code Playgroud)

我也试过:

  select distinct department_name
    from dbo.departments
group by department_name;
Run Code Online (Sandbox Code Playgroud)

所以这让我相信我可能在值中隐藏了字符,果然,当我检查字符串的长度时,它们返回了不同的值。所以,我决定使用堆栈溢出这个问题中的函数来定位隐藏字符。奇怪的是,这只返回 SPACE。然后我尝试了以下查询,它根本没有区别:

select distinct ltrim(rtrim(department_name)) as department_name
  from dbo.departments;
Run Code Online (Sandbox Code Playgroud)

出于好奇,我将这些值转换为VARBINARY并注意到它们具有完全相同的二进制值,并且对二进制值执行 aDISTINCT确实会产生一个唯一的结果集。

我也尝试在VARCHARNVARCHAR和到不同的排序规则之间进行转换(值在同一列中,在使用 Latin1_General_CI_AI 的同一数据库中)。我真的需要能够从这张表中得到一个不同的集合。有谁知道可能导致这个问题的原因是什么?

更新

经过进一步调查,这个问题似乎只发生在以十六进制值结尾的字符串中0xA000。列中不以该字符结尾的任何值都可以。

更新 2

如果我0xA000从字符串中删除字符,我可以DISTINCT像这样正常应用:

DECLARE @binary VARBINARY(8) = 0xA000;
DECLARE @string VARCHAR(8) = CONVERT(VARCHAR(MAX), @binary);
 UPDATE dbo.departments
    SET department_name = REPLACE(department_name, @string, '');
Run Code Online (Sandbox Code Playgroud)

但这不会长期有效,因为用户可以更新此表,我需要调整每个查询以在WHERE子句中进行替换。我现在正在使用一种解决方法,它只不过是MIN用于返回长度最短的条目。这不太理想,因为 distinct 的问题也会影响大多数其他语言元素,例如GROUP BY …

sql-server collation distinct sql-server-2016

7
推荐指数
1
解决办法
1677
查看次数

PostgreSQL:排序规则“C”和“C.UTF-8”之间的区别

在 PostgreSQL 中,排序规则CC.UTF-8?

两者都显示在pg_collation. 无论数据库的实际编码是什么,它是否可能与编码C.UTF-8相同?CUTF-8

postgresql collation encoding locales

7
推荐指数
2
解决办法
8887
查看次数

相似匹配与比较之间的关系

like \'foo%\'我天真地认为 a和 a之间的关系>= \'foo\'是后者与前者以及索引顺序中后面的一些附加行相匹配。更一般地说,我认为对于给定的文本,t字符列上的索引分为四个区域,分别是

\n
    \n
  1. <( )之前的条目t
  2. \n
  3. 条目等于 ( =) t
  4. \n
  5. >大于 ( )t且仍以t( ) 作为前缀的条目like concat(t, \'%\')以及
  6. \n
  7. 其余的部分,
  8. \n
\n

并且这些区域是连续的并且按顺序排列。

\n

此外,具有t前缀 ( like concat(t, \'%\')) 的所有行也在索引中形成一个连续区域,并且该区域在其开头包含区域 2(这意味着它恰好是区域 2 和 3 在一起)。

\n

但事情可能没那么简单。例如,在 SQL Server 中,单词在排序规则中H\xc3\xa4user比较等于,并且两者都是。HaeuserGerman_PhoneBook_CI_AI>= \'Ha\'

\n

但是,仅Haeuser匹配like \'Ha%\',因此有关前缀的附加假设并不完全成立。

\n

你可以在这个小提琴中看到这一点。 …

sql-server collation order-by

7
推荐指数
1
解决办法
427
查看次数