【问题标题】:Oracle SQL Stored Procedure with Oracle reserved words passed to variable将 Oracle 保留字传递给变量的 Oracle SQL 存储过程
【发布时间】:2018-10-08 17:34:06
【问题描述】:

我有一个存储过程,它传递了一串用空格分隔的值,然后在表中进行搜索并返回列具有任何这些值的数据。一切顺利,直到用户需要传递没有返回任何内容的“INDEX END UNKNOWN PROCESS”,即使存在具有这些值的数据:

    CREATE OR REPLACE PROCEDURE  Searches
(
   QUEUE             IN TYPES.CHAR50,  
   P_CURSOR          IN OUT SYS_REFCURSOR  
)   
AS

BEGIN

OPEN P_CURSOR FOR
 SELECT *
 FROM tablez t
 WHERE /* If the subquery returns UNKNOWN, END, PROCESS, INDEX which are Oracle reserved words the main query won't return any results */
       /* In order to pass this inconsistency, I concatenated XYZ to both sides when using IN Clause                                   */
       CONCAT(LTRIM(RTRIM(t.QUEUECD)),'XYZ') IN ( SELECT CONCAT(LTRIM(RTRIM(tr.prom)),'XYZ')     
                                                        FROM ( SELECT regexp_substr(QUEUE,'[^ ]+', 1, LEVEL) prom 
                                                               FROM dual 
                                                               CONNECT BY regexp_substr(QUEUE, '[^ ]+', 1, LEVEL) IS NOT NULL 
                                                              ) tr   
                                                       )
    ;

END Searches;

因此,我将代码更改为使用 regexp_substr,并且在进行比较时仅连接“XYZ”返回值。但这是一个临时修复,因为 QUEUECD 是数据库中的索引列,并且在 WHERE 子句中使用 CONCAT 会导致大数据上的性能问题。 您对如何提高性能或以不同的方式传递值列表有什么建议吗?

谢谢!

【问题讨论】:

    标签: sql oracle performance stored-procedures reserved-words


    【解决方案1】:

    带有 Oracle 保留字的 Oracle SQL 存储过程传递给 变量

    这看起来是一个不同的问题。看:没有办法将“保留字”作为变量的值传递——当你有 varchar 变量时,这个值就是一个文本——仅此而已。

    我制作了一个示例表并测试了一个没有串联“XYZ”的查询—​​—我没有这样的问题。也许在记录的末尾或开头有一些白色的不可打印的字符?

    关于:

    您对如何提高性能或以不同的方式传递值列表有什么建议吗?

    是的。将集合(嵌套表)作为参数传递。例如:

    create or replace type T_TAB_STRING as table of varchar2(4000);
    

    接下来,将 QUEUE 的类型从 TYPES.CHAR50 更改为 T_TAB_STRING

    然后您可以使用 table() 表达式在查询中取消嵌套集合:

    SELECT *
    FROM tablez t
    WHERE t.QUEUECD IN ( SELECT /*+ DYNAMIC_SAMPLING(tr, 2) */
                             *
                           FROM TABLE(QUEUE) tr
                       )
    ;
    

    动态采样提示用于强制 DB 检查集合中有多少元素。如果没有该数据库,则假定它的大小为 1 个块(通常为 8k),因此 CBO 可以选择进行全扫描而不是索引扫描。

    如果您不能使用该提示,或者由于某种原因它不起作用,还有其他方法可以帮助 CBO 处理查询中的集合。它正在为该集合实现可扩展优化器接口。它是由 Adrian Billington 在this article 中编写的。

    【讨论】:

    • 谢谢罗伯图斯。该数据最近已从 DB2 转换为 Oracle,是的,很多数据都有尾随/前导空格。我会在没有 concat 的情况下试一试,然后检查修剪是否可以工作。我必须检查我是否有足够的访问权限来使用您的性能改进想法。谢谢!
    • 我们的数据库似乎没有激活DYNAMIC_SAMPLING功能,我们不允许使用它。
    • There is 非常好的示例如何为嵌套表类型实现可扩展优化器接口。如果没有可扩展优化器接口或动态采样提示,请不要在查询中直接使用集合 - 通常会很慢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    相关资源
    最近更新 更多