UDF 中的 COLLATE 未按预期工作

2023-11-21

我有一个带有文本字段的表格。我想选择文本全部大写的行。该代码按其应有的方式工作,并返回ABC:

SELECT txt
FROM (SELECT 'ABC' AS txt UNION SELECT 'cdf') t
WHERE 
txt COLLATE SQL_Latin1_General_CP1_CS_AS = UPPER(txt)

然后我创建 UDF(按照建议here):

CREATE FUNCTION [dbo].[fnsConvert]
(
      @p NVARCHAR(2000) ,
      @c NVARCHAR(2000)
)
RETURNS NVARCHAR(2000)
AS
    BEGIN
        IF ( @c = 'SQL_Latin1_General_CP1_CS_AS' )
            SET @p = @p COLLATE SQL_Latin1_General_CP1_CS_AS
        RETURN @p    
    END

并按如下方式运行它(对我来说这看起来是等效的代码):

SELECT txt
FROM (SELECT 'ABC' AS txt UNION SELECT 'cdf') t
WHERE 
dbo.fnsConvert(txt, 'SQL_Latin1_General_CP1_CS_AS') = UPPER(txt)

但是,这会返回ABCcdf.

为什么会这样,我该如何让它发挥作用?

PS 我在这里需要 UDF 才能从 .Net LINQ2SQL 提供程序调用区分大小写的比较。


变量不能有自己的排序规则。它将始终使用服务器的默认值。检查一下:

--我声明了三个变量,每个变量都有自己的排序规则 - 至少有人可能这么认为:

DECLARE @deflt VARCHAR(100) = 'aBc'; --Latin1_General_CI_AS in my system
DECLARE @Arab VARCHAR(100) = 'aBc' COLLATE Arabic_100_CS_AS_WS_SC;
DECLARE @Rom VARCHAR(100) = 'aBc' COLLATE Romanian_CI_AI

——现在检查一下。所有三个变量都被视为系统的默认排序规则:

SELECT [name], system_type_name, collation_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT @deflt AS Deflt, @Arab AS Arab, @Rom AS Rom'
                                          ,N'@deflt varchar(100), @Arab varchar(100),@Rom varchar(100)'
                                          ,0);

/*
name    system_type_name    collation_name
Deflt   varchar(100)        Latin1_General_CI_AS
Arab    varchar(100)        Latin1_General_CI_AS
Rom     varchar(100)        Latin1_General_CI_AS
*/

--现在我们检查“aBc”与“ABC”的简单比较

SELECT CASE WHEN @deflt = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckDefault
      ,CASE WHEN @Arab = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckArab
      ,CASE WHEN @Rom = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckRom

/*CI    CI  CI*/

--但是我们可以为一个给定的操作指定排序规则!

SELECT CASE WHEN @deflt = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckDefault
      ,CASE WHEN @Arab = 'ABC' COLLATE Arabic_100_CS_AS_WS_SC THEN 'CI' ELSE 'CS' END AS CheckArab
      ,CASE WHEN @Rom = 'ABC' COLLATE Romanian_CI_AI THEN 'CI' ELSE 'CS' END AS CheckRom

/*CI    CS  CI*/

--但是表的列会有不同的行为:

CREATE TABLE #tempTable(deflt VARCHAR(100)
                       ,Arab VARCHAR(100) COLLATE Arabic_100_CS_AS_WS_SC
                       ,Rom VARCHAR(100) COLLATE Romanian_CI_AI);

INSERT INTO #tempTable(deflt,Arab,Rom) VALUES('aBc','aBc','aBc');

SELECT [name], system_type_name, collation_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT * FROM #tempTable',NULL,0);
DROP TABLE #tempTable;

/*
name    system_type_name    collation_name
deflt   varchar(100)        Latin1_General_CI_AS
Arab    varchar(100)        Arabic_100_CS_AS_WS_SC
Rom     varchar(100)        Romanian_CI_AI
*/

--这也适用于声明表变量。比较“知道”指定的排序规则:

DECLARE @TableVariable TABLE(deflt VARCHAR(100)
                            ,Arab VARCHAR(100) COLLATE Arabic_100_CS_AS_WS_SC
                            ,Rom VARCHAR(100) COLLATE Romanian_CI_AI);

INSERT INTO @TableVariable(deflt,Arab,Rom) VALUES('aBc','aBc','aBc');

SELECT CASE WHEN tv.deflt = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckDefault
      ,CASE WHEN tv.Arab = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckArab
      ,CASE WHEN tv.Rom = 'ABC' THEN 'CI' ELSE 'CS' END AS CheckRom
FROM @TableVariable AS tv

/*CI    CS  CI*/

更新一些文档

在这个链接您可以阅读有关详细信息。整理不改变值. It 应用规则(相关NOT NULL它不会更改值,而只是添加规则是否NULL可以设置也可以不设置)。

文档说得很清楚

是一个子句,可应用于数据库定义或列定义以定义排序规则,或应用于字符串表达式以应用排序规则转换。

稍后你会发现

  1. 创建或更改数据库
  2. 创建或更改表列
  3. 转换表达式的排序规则

更新2:解决方案的建议

如果您想控制比较是进行 CS 还是 CI,您可以尝试以下操作:

DECLARE @tbl TABLE(SomeValueInDefaultCollation VARCHAR(100));
INSERT INTO  @tbl VALUES ('ABC'),('aBc');

DECLARE @CompareCaseSensitive BIT = 0;
DECLARE @SearchFor VARCHAR(100) = 'aBc';

SELECT *
FROM @tbl 
WHERE (@CompareCaseSensitive=1 AND SomeValueInDefaultCollation=@SearchFor COLLATE Latin1_General_CS_AS)
   OR (ISNULL(@CompareCaseSensitive,0)=0 AND SomeValueInDefaultCollation=@SearchFor COLLATE Latin1_General_CI_AS);

With @CompareCaseSensitive set to 1它只会返回aBc, with NULL or 0它将返回两行。

这是——肯定的! - 性能比 UDF 好得多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UDF 中的 COLLATE 未按预期工作 的相关文章

  • T-SQL:用最新的非空值替换 NULL 的最佳方法?

    假设我有这张表 id value 1 5 2 4 3 1 4 NULL 5 NULL 6 14 7 NULL 8 0 9 3 10 NULL 我想编写一个查询来替换任何NULL值与表中最后一个不为空的值在那一栏里 我想要这个结果 id va
  • 根据日期顺序排名

    我的数据如下 Heading Date A 2009 02 01 B 2009 02 03 c 2009 02 05 d 2009 02 06 e 2009 02 08 我需要如下排名 Heading Date Rank A 2009 02
  • 更改列时快速删除并重新创建多个索引、视图、统计信息

    我的 项目 表中有一个 StoreNumber 列 我想将其更改为 NOT NULL 我最近清理了所有旧数据 以便不存在空条目 但是 当我执行以下语句时 由于对各种视图 索引和统计信息的多重依赖 它失败了 ALTER TABLE Proje
  • 快速查询最新记录的方法?

    我有一张这样的表 USER PLAN START DATE END DATE 1 A 20110101 NULL 1 B 20100101 20101231 2 A 20100101 20100505 在某种程度上 如果END DATE i
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 如何通过 SQL 表关联 SQL 中的实体

    我是数据库设计的初学者 我需要为项目创建数据库 我可以用面向对象的术语解释我想要做什么 值得庆幸的是 数据库专家会很友善地向我解释如何在数据库方面处理这个问题 我想创建一个与位置实体 州 城市 有关系的用户 ID 名称 实体 所以在编程语言
  • 弹簧隔离支持吗? SQL快照隔离

    我们正在使用 SQL Server 快照隔离可能是提高性能和解决一些死锁问题的好方法 假设我们确实需要更改为快照隔离 我似乎找不到一种简单的方法来在 Springs 上启用快照隔离 Transactional 我发现以下 hibernate
  • 使用子查询 select 创建新表

    我试图从子查询选择创建一个新表 但出现以下错误 附近的语法不正确 SELECT INTO foo FROM SELECT DATEPART MONTH a InvoiceDate as CalMonth DATEPART YEAR a In
  • 如何从 SQL Server 2008 查询结果中删除“NULL”

    我有一个包含 59 列和超过 17K 行的表 很多行都有NULL在某些列中 我想删除NULL以便查询返回空白 而不是NULL 我可以运行一些更新功能来替换所有NULL with 使用 SQL Server 2008R2 Management
  • 如何识别拼写不同的相似单词

    我想从数据库中过滤掉重复的客户名称 一位客户可能有多个同名但拼写差异不大的系统条目 这是一个示例 名为 Brook 的客户可能有 3 个系统条目 有了这个变化 布鲁克 贝尔塔 布鲁克 贝尔塔 比鲁克 贝尔塔 假设我们将此名称放入一个数据库列
  • 获取带有计数的不同记录

    我有一张桌子personid and msg列 personid msg 1 msg1 2 msg2 2 msg3 3 msg4 1 msg2 我想得到总计msg对于每个personid 我正在尝试这个查询 select distinct
  • 解析带下划线的 SQL Server 数字文字

    我想知道它为什么有效以及为什么它不返回错误 SELECT 2015 11 Result 11 2015 第二种情况 SELECT 2 1 a a 2 1 检查元数据 SELECT name system type name FROM sys
  • SQL查询查找表的主键?

    我怎样才能找到哪一列首要的关键使用查询来创建表 这是重复的question https stackoverflow com questions 893874 mysql determine tables primary key dynami
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec
  • Spark SQL 中的 SQL LIKE

    我正在尝试使用 LIKE 条件在 Spark SQL 中实现联接 我正在执行连接的行看起来像这样 称为 修订 Table A 8NXDPVAE Table B 4 8 NXD V 在 SQL Server 上执行联接 A revision
  • SQL Server 数据库架构版本控制和更新

    对于我的应用程序 我必须支持更新方案 并且数据库可能会受到影响 我希望能够从旧版本更新到最新版本 而无需安装中间版本 例如 假设我有版本 A 最旧的版本 B 中间版本 和 C 新版本 我希望能够将版本 A 直接更新到版本 C 对于应用程序文
  • 使用加权行概率从 PostgreSQL 表中选择随机行

    输入示例 SELECT FROM test id percent 1 50 2 35 3 15 3 rows 你会如何编写这样的查询 平均 50 的时间我可以获得 id 1 的行 35 的时间 id 2 的行 15 的时间 id 3 的行
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 如何获取自定义订单的结果? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 代替ASC or DESC 我希望我的查询结果采用特定的自定义顺序 例如 如果我想要的结果不是 A B C D 而是 P A L H 该怎么

随机推荐

  • 为什么我的断点在 Visual Studio 中重复?

    我最近开始在 Visual Studio 2010 中遇到断点问题 当我设置断点然后开始调试时 另一个断点出现在附近的其他行上 下面的屏幕截图显示了设置断点后的编辑器以及断点窗口 一旦我开始调试 断点就会重复 如以下屏幕截图所示 为什么会发
  • CodeIgniter 站点在子目录中,htaccess 文件可能会干扰主目录中的 htaccess 文件?

    在我的 CodeIgniter 网站 托管在 GoDaddy 上 中 导航到任何页面但索引都会出现此错误 未指定输入文件 谷歌搜索了一下 似乎原因一定与我的 htaccess 情况有关 设置的方式 也许最终会改变 是我的 CI 站点位于主域
  • NuGet 包未将 XMLDoc 文件与 dll 一起复制到 bin

    我正在使用 NuGet GUI 并尝试将 XML 文件与我的 DLL 一起包含以将帮助与 DLL 一起分发 当我在任何项目中安装包时 它都会成功添加 DLL 引用 但在添加包的项目的 bin 文件夹内未生成 XML 文件 XML 文件在pa
  • 如何计算 Ruby 数组中的重复元素

    我有一个排序数组 FATAL
  • Visual Studio 2005.RC 文件包括

    我正在 Visual Studio 2005 上使用 C 进行编程 我的问题涉及 rc 文件 您可以手动将包含指令 如 include blah h 放置在 rc 文件的顶部 但这是个坏消息 因为第一次有人在资源编辑器中打开 rc 文件时
  • 什么是 Android MultiDex?

    有很多关于 MultiDex 的帖子 我有时经历过解决错误 包括multiDexEnabled true in the defaultConfig我的 build gradle 部分 但是 这个功能到底是什么 使用场景有哪些 Quoting
  • Git 追踪上游

    我正在开发一个项目 并且有一个中央 git 存储库 该项目是一个框架 是许多分叉的基线 是否可以为分叉配置我的本地工作存储库 以跟踪项目的中心作为原点 并将骨架的主控作为名为上游的单独分支跟踪 跟踪骨架的主控以挑选对骨架的更改 我想我希望我
  • JavaScript“this”关键字和箭头函数

    Here this箭头函数中的关键字指向obj的可变环境 var greeting hi const obj greeting hey fo const greeting hola const arrowFo gt console log
  • 如何在数据框中添加一列来说明每行来自哪个工作表名称? Python

    我正在使用一个有五张纸的数据框 我想使用其中的四张 所以我可以将其加载到 df pd read excel xls sheet name a b c d 但现在我想添加一列来说明每行所在的工作表 但我不知道如何执行此操作 我尝试过这样的事情
  • Google-api-php 刷新令牌返回 invalid_grant

    我几乎搜索了谷歌第一页的所有结果 但似乎找不到答案 我正在使用 Google API 的刷新令牌并接收 Error refreshing the OAuth2 token message error invalid grant 我在做什么
  • 日期格式转换javascript

    我正在尝试使用 javascript 将 2013 年 7 月 24 日 转换为 DD MM YYYY 但我不断收到错误消息 我在用new Date July 24 2013 format DD MM YYYY 我缺少什么 Date对象没有
  • Python3.4 错误 - 无法启用可执行堆栈,因为共享对象需要:无效参数

    我一直在尝试安装OpenCV在 Windows 上的 Bash Linux 的 Windows 子系统 wsl 环境中 事实证明这非常困难 我想我已经非常接近了 但是进入 python 后 import cv2给出以下错误 ImportEr
  • 在文档 (.docx) 的特定位置添加图像?

    我使用 Python docx 生成 Microsoft Word 文档 用户希望当他写下这样的内容时 大家早上好 这是我的 profile img s 你喜欢吗 在 HTML 字段中 我创建一个 Word 文档 并从数据库中恢复用户的图片
  • 按值对数组进行排序并存储在变量中

    array array 5 4 6 8 5 3 4 6 1 我想排序 array like asort确实如此 但问题是asort是一个函数 它的乘积不能存储在变量中 我怎样才能做这样的事情 array array 5 4 6 8 5 3
  • 如何在 TextView 中的每个单词上使用 onTouchListeners?

    我想将 onTouchListeners 分配给 TextView 中的每个单词 不是链接到互联网上的某些内容 而是为了继续应用程序内的游戏逻辑 此时我的游戏的一般操作是查看 TextView 触摸一个单词 如果它是您获胜的目标单词 否则根
  • 如何从类函数内部访问对象属性[重复]

    这个问题在这里已经有答案了 我的 Javascript 类之一有时需要用 Json 更新 我一直在做一个函数 在给定一个 id 的情况下更新数据数组 但现在我想把它做得更封装 函数更新 在类内部 我做了什么 function File da
  • Angular 2 使用 FormBuilder 访问嵌套 FormArray

    首先 我刚刚从 Angular 2 开始 我正在尝试构建一个嵌套表单并验证它 这是我的 ts 文件的一部分 ngOnInit this myForm this formBuilder group projects this formBuil
  • JavaScript 的正则表达式表示法有什么问题?

    我正在读道格拉斯 克罗克福德的网页 JavaScript 世界上最容易被误解的编程语言 我不禁注意到 在 设计错误 下 他提到了 文字正则表达式的符号 他到底在说什么 JavaScript 的正则表达式表示法有什么问题 为什么 可能与它迫使
  • 将取消引用的智能指针的地址传递给需要原始指针的函数

    假设我正在使用需要使用原始指针的库或框架 使用拥有一些数据的智能指针 然后将取消引用的智能指针的地址传递给需要原始指针的函数 这是有效的做法吗 是的 这是有效的做法 这std智能指针有一个get 成员函数正是为了这个目的 一般来说 当您通过
  • UDF 中的 COLLATE 未按预期工作

    我有一个带有文本字段的表格 我想选择文本全部大写的行 该代码按其应有的方式工作 并返回ABC SELECT txt FROM SELECT ABC AS txt UNION SELECT cdf t WHERE txt COLLATE SQ