转义字符以用于 Oracle 的 Xmltable
Escaping characters for use with Oracle's Xmltable
我正在使用 Xmltable
将逗号分隔的电子邮件地址字段转换为 table 个值。
WITH
data AS
(
select 1 ID, 'foo&bar@domain.tld,bar@domain.tld' recipients from dual
)
select ID, trim(COLUMN_VALUE) recipient
from data,xmltable(('"'|| REPLACE( recipients , ',', '","') || '"'))
产生错误:
[72000][19112] ORA-19112: error raised during evaluation: XVM-01003:
[XPST0003] Syntax error at '"foo' 1
"foo&bar@domain.tld","bar@domain.tld" - ^
但是,当我用实体值 (&
) 替换 &
时:
WITH
DATA AS
(
select 1 ID, 'foo&bar@domain.tld,bar@domain.tld' recipients from dual
)
select ID
-- & --> &
, replace( trim(COLUMN_VALUE), '&', '&') recipient
from data
-- & --> &
,xmltable(('"'|| REPLACE( replace( recipients, '&','&') , ',', '","') || '"'))
查询有效:
ID,RECIPIENT
1,foo&bar@domain.tld
1,bar@domain.tld
我想可能有其他字符在电子邮件地址中有效,但对于 Xmltable
来说会有问题。
有更好的方法吗?
您可以使用 the built-in dbms_xmlgen.convert()
function:
with data (id, recipients) as
(
select 1, 'foo&bar@domain.tld,bar@domain.tld' from dual
)
select d.id, dbms_xmlgen.convert(x.column_value.getstringval(), 1) as recipient
from data d
cross join
xmltable(('"' || replace(dbms_xmlgen.convert(d.recipients, 0), ',', '","') || '"')) x
ID RECIPIENT
---------- ------------------------------
1 foo&bar@domain.tld
1 bar@domain.tld
内呼dbms_xmlgen.convert(d.recipients, 0)
给你
foo&bar@domain.tld,bar@domain.tld
将其修改为用双引号将每个逗号分隔值括起来并分成多行后,您最终得到 column_value
为:
foo&bar@domain.tld
bar@domain.tld
所以外部 dbms_xmlgen.convert(x.column_value.getstringval(), 1)
将任何编码实体转换回它们的普通版本。
如果您在 PL/SQL 上下文中执行此操作,那么您可以使用 dbms_xmlgen.entity_encode
和 dbms_xmlgen.entity_decode
而不是固定的 0 和 1,但它们在普通 SQL.
(无论如何有 only five entities 需要担心,但您仍然不妨考虑所有这些 - 无论它们在电子邮件地址中是否有效 - 并且使用这样的函数调用可能会减少对未来维护者的混淆...)
我正在使用 Xmltable
将逗号分隔的电子邮件地址字段转换为 table 个值。
WITH
data AS
(
select 1 ID, 'foo&bar@domain.tld,bar@domain.tld' recipients from dual
)
select ID, trim(COLUMN_VALUE) recipient
from data,xmltable(('"'|| REPLACE( recipients , ',', '","') || '"'))
产生错误:
[72000][19112] ORA-19112: error raised during evaluation: XVM-01003: [XPST0003] Syntax error at '"foo' 1 "foo&bar@domain.tld","bar@domain.tld" - ^
但是,当我用实体值 (&
) 替换 &
时:
WITH
DATA AS
(
select 1 ID, 'foo&bar@domain.tld,bar@domain.tld' recipients from dual
)
select ID
-- & --> &
, replace( trim(COLUMN_VALUE), '&', '&') recipient
from data
-- & --> &
,xmltable(('"'|| REPLACE( replace( recipients, '&','&') , ',', '","') || '"'))
查询有效:
ID,RECIPIENT
1,foo&bar@domain.tld
1,bar@domain.tld
我想可能有其他字符在电子邮件地址中有效,但对于 Xmltable
来说会有问题。
有更好的方法吗?
您可以使用 the built-in dbms_xmlgen.convert()
function:
with data (id, recipients) as
(
select 1, 'foo&bar@domain.tld,bar@domain.tld' from dual
)
select d.id, dbms_xmlgen.convert(x.column_value.getstringval(), 1) as recipient
from data d
cross join
xmltable(('"' || replace(dbms_xmlgen.convert(d.recipients, 0), ',', '","') || '"')) x
ID RECIPIENT
---------- ------------------------------
1 foo&bar@domain.tld
1 bar@domain.tld
内呼dbms_xmlgen.convert(d.recipients, 0)
给你
foo&bar@domain.tld,bar@domain.tld
将其修改为用双引号将每个逗号分隔值括起来并分成多行后,您最终得到 column_value
为:
foo&bar@domain.tld
bar@domain.tld
所以外部 dbms_xmlgen.convert(x.column_value.getstringval(), 1)
将任何编码实体转换回它们的普通版本。
如果您在 PL/SQL 上下文中执行此操作,那么您可以使用 dbms_xmlgen.entity_encode
和 dbms_xmlgen.entity_decode
而不是固定的 0 和 1,但它们在普通 SQL.
(无论如何有 only five entities 需要担心,但您仍然不妨考虑所有这些 - 无论它们在电子邮件地址中是否有效 - 并且使用这样的函数调用可能会减少对未来维护者的混淆...)