Sybase/SAP ASE 中的 LIKE 子句在末尾修剪了吗?
LIKE clause in Sybase/SAP ASE trimmed at the end?
下面的emp table没有以三个空格结尾的ENAME。但是,以下 SQL 语句的行为就像子句在末尾被修剪(如 '%' 模式),因为它 return 包含所有记录:
select ENAME from dbo.emp where ENAME like '% '
我尝试了许多其他数据库平台(包括 SQL Server、SQL Anywhere、Oracle、PostgreSQL、MySQL 等),我见过这种情况仅在 Sybase/SAP ASE(版本 16)中。这是错误还是 "by design"?在这方面 online spec 中没有发现任何具体内容。
我正在寻找一个通用的修复程序,以对模式应用一些简单的转换以及 return 对任何其他平台的期望。事先不知道该字段是什么数据类型或它包含什么类型的数据。
这是由 ASE 中的 VARCHAR 语义引起的,它总是会在对值进行操作之前从值中去除前导 space。这在使用之前应用于字符串 '% ',因为根据定义这是一个 VARCHAR 值。这确实是 ASE 的特殊语义。
现在,您可以尝试使用 [ ] 通配符来匹配 space 来解决这个问题,但有一些事情需要注意。首先,匹配的列 (ENAME) 必须是 CHAR,而不是 VARCHAR,否则任何试验 spaces 也会在存储之前被删除。假设该列是 CHAR,那么不幸的是,使用模式 '%[ ][ ][ ]' 似乎仍然不起作用。我认为这里可能还有一些尾随-space-剥离。
解决此问题的最佳方法是使用不会出现在数据中的人为字段结束定界符,例如
ENAME||'~EOF~' like '% ~EOF~'
这行得通。但请注意,列 ENAME 必须仍然是 CHAR 而不是 VARCHAR。
喜欢的行为以某种方式记录在 here 中。
对于 VARCHAR 列,这将永远不会起作用,因为 ASE 会删除尾随空格
对于 CHAR,这取决于您如何插入数据..在 char(10) 列中,如果您插入 2 个字符,ASE 将在这 2 个字符后添加 8 个空格,使它们成为 10..所以当您query ,你将得到这个 2 个字符的条目作为结果集的一部分,因为它包含超过 3 个尾随空格..
如果这对您来说不是问题,您可以使用 char_index () 而不是 like,它会计算尾随空格并且不会像 like 那样截断它们,因此您可以这样写:
select ENAME from dbo.emp where char_index(' ',ENAME) >0
或者您可以计算尾随空格,然后检查后面是否有 3 个空格,例如:
select a from A
where charindex(' ',a) > (len(a) - len(convert (varchar(10) , a)))
现在再次 ,如果数据以非均匀计数插入,这将使您获得比预期更多的行,但如果您确切知道要搜索什么,则效果会很好.
SELECT 从 dbo.emp 改名,其中 RIGHT(ENAME ,3) = ' '
下面的emp table没有以三个空格结尾的ENAME。但是,以下 SQL 语句的行为就像子句在末尾被修剪(如 '%' 模式),因为它 return 包含所有记录:
select ENAME from dbo.emp where ENAME like '% '
我尝试了许多其他数据库平台(包括 SQL Server、SQL Anywhere、Oracle、PostgreSQL、MySQL 等),我见过这种情况仅在 Sybase/SAP ASE(版本 16)中。这是错误还是 "by design"?在这方面 online spec 中没有发现任何具体内容。
我正在寻找一个通用的修复程序,以对模式应用一些简单的转换以及 return 对任何其他平台的期望。事先不知道该字段是什么数据类型或它包含什么类型的数据。
这是由 ASE 中的 VARCHAR 语义引起的,它总是会在对值进行操作之前从值中去除前导 space。这在使用之前应用于字符串 '% ',因为根据定义这是一个 VARCHAR 值。这确实是 ASE 的特殊语义。
现在,您可以尝试使用 [ ] 通配符来匹配 space 来解决这个问题,但有一些事情需要注意。首先,匹配的列 (ENAME) 必须是 CHAR,而不是 VARCHAR,否则任何试验 spaces 也会在存储之前被删除。假设该列是 CHAR,那么不幸的是,使用模式 '%[ ][ ][ ]' 似乎仍然不起作用。我认为这里可能还有一些尾随-space-剥离。
解决此问题的最佳方法是使用不会出现在数据中的人为字段结束定界符,例如
ENAME||'~EOF~' like '% ~EOF~'
这行得通。但请注意,列 ENAME 必须仍然是 CHAR 而不是 VARCHAR。
喜欢的行为以某种方式记录在 here 中。
对于 VARCHAR 列,这将永远不会起作用,因为 ASE 会删除尾随空格
对于 CHAR,这取决于您如何插入数据..在 char(10) 列中,如果您插入 2 个字符,ASE 将在这 2 个字符后添加 8 个空格,使它们成为 10..所以当您query ,你将得到这个 2 个字符的条目作为结果集的一部分,因为它包含超过 3 个尾随空格..
如果这对您来说不是问题,您可以使用 char_index () 而不是 like,它会计算尾随空格并且不会像 like 那样截断它们,因此您可以这样写:
select ENAME from dbo.emp where char_index(' ',ENAME) >0
或者您可以计算尾随空格,然后检查后面是否有 3 个空格,例如:
select a from A
where charindex(' ',a) > (len(a) - len(convert (varchar(10) , a)))
现在再次 ,如果数据以非均匀计数插入,这将使您获得比预期更多的行,但如果您确切知道要搜索什么,则效果会很好.
SELECT 从 dbo.emp 改名,其中 RIGHT(ENAME ,3) = ' '