我希望格式化sys_guid()函数的结果,例如this answer中提出的
select regexp_replace(rawtohex(sys_guid())
, '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})'
, '\1-\2-\3-\4-\5')
as FORMATTED_GUID
from dual
出于性能原因,我想避免使用regexp_replace(因为我处理大量记录)。
我的场景可以简化为这个用例:
select rawtohex(sys_guid()) GUID
from dual connect by level <= 2;
显然,我不能使用substr和concatenation,因为每个SUBSTR都会处理不同的SYS_GUID。我还想留在SQL中,没有上下文切换到PL / SQL函数。
任何想法如何使用掩码格式化SQL中的字符串类似于日期或数字:
to_char(rawtohex(sys_guid(),'CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC') /* note, this is clear illegal */
答案 0 :(得分:4)
不幸的是,您不能在数字格式中包含字符串文字,否则您可以将十六进制字符串转换为数字然后再返回,在格式掩码中插入文字在正确的位置 - 但您只能这样做日期。
您可以使用substr()
,因为这些位置是固定的。你担心的是
显然,我不能使用substr和concatenation,因为每个SUBSTR都会处理不同的SYS_GUID。
使用子查询因子分析(a.ka.一个公用表表达式/ CTE)意味着来自该CTE的行的substr()
调用都看到相同的GUID;这种方法不会为每个生成一个新的SYS_GUID。
with t as (
select rawtohex(sys_guid()) guid from dual
connect by level <= 2
)
select guid, substr(guid, 1, 8)
||'-'|| substr(guid, 9, 4)
||'-'|| substr(guid, 13, 4)
||'-'|| substr(guid, 17, 4)
||'-'|| substr(guid, 21, 12) as formatted_guid
from t;
GUID FORMATTED_GUID
-------------------------------- ----------------------------------------
2F6BA62518F926D0E0534D49E50ABB46 2F6BA625-18F9-26D0-E053-4D49E50ABB46
2F6BA62518FA26D0E0534D49E50ABB46 2F6BA625-18FA-26D0-E053-4D49E50ABB46
比大量数据的正则表达式快得多。循环中有100000个值(在PL / SQL块中,在循环内执行最少量的工作以使其实际正确评估,并使用dbms_utility.get_cpu_time
检查已用时间)正则表达式版本大约需要2.51秒,而子串版本大约需要0.29秒。您的系统当然会得到不同的数量,但它应该仍然大致相同的数量级。