Sub*_*isM 2 oracle oracle10g oracle11g
我正在使用查询来检查 chr(0) 在 regexp_like 中的行为。
CREATE TABLE t1(a char(10));
INSERT INTO t1 VALUES('0123456789');
SELECT CASE WHEN REGEXP_LIKE(a,CHR(0)) THEN 1 ELSE 0 END col, DUMP(a)
FROM t1;
Run Code Online (Sandbox Code Playgroud)
我得到的输出是这样的 -
col dump(a)
----------- -----------------------------------
1 Typ=96 Len=10: 48,49,50,51,52,53,54,55,56,57
Run Code Online (Sandbox Code Playgroud)
我完全困惑了,如果没有如转储(a)所示的 chr(0),regexp_like 如何在列中找到 chr(0) 并返回 1?这里不应该返回0吗?
CHR(0)是 C 编程语言(以及其他语言)中用于终止字符串的字符。
当您传递CHR(0)给该函数时,它将依次将其传递给较低级别的函数,该函数将解析您传入的字符串并从该字符串构建正则表达式模式。该正则表达式模式将看到CHR(0)并认为它是字符串终止符,并忽略模式的其余部分。
使用以下命令更容易看到该行为REGEXP_REPLACE:
SELECT REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' )
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
当你运行这个时会发生什么:
CHR(0)被编译成正则表达式并成为字符串终止符。a,并找到可以在 之前匹配的零长度字符串,因此它用给出的输出替换a之前匹配的任何内容。addab为db。d.你会得到输出:
dadbdcd_ded
Run Code Online (Sandbox Code Playgroud)
(其中 _ 是CHR(0)字符。)
注意:CHR(0)输入中的 不会被替换。
如果您使用的客户端程序也在截断字符串,CHR(0)您可能看不到完整的输出(这是您的客户端如何表示字符串的问题,而不是 Oracle 的输出的问题),但也可以使用以下方式显示DUMP():
SELECT DUMP( REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' ) )
FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
输出:
Typ=1 Len=11: 100,97,100,98,100,99,100,0,100,101,100
Run Code Online (Sandbox Code Playgroud)
[TL;DR]那么发生了什么
REGEXP_LIKE( '1234567890', CHR(0) )
Run Code Online (Sandbox Code Playgroud)
它将创建一个零长度字符串正则表达式模式,并将在1字符之前查找零长度匹配 - 它会找到该匹配,然后返回它已找到匹配项。
| 归档时间: |
|
| 查看次数: |
5795 次 |
| 最近记录: |