Oracle SQL存储过程与Oracle保留字传递给变量

时间:2018-04-27 20:17:57

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

我有一个存储过程,它传递一个用空格分隔的值字符串,然后在表中搜索并返回列中包含任何值的数据。一切顺利,直到用户需要通过' 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导致大数据上的性能问题。 您对如何提高性能或以不同方式传递值列表有任何建议吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

  

传递给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检查集合中有多少元素。如果没有该DB,则假设它的大小为1个块(通常为8k),因此CBO可以选择进行全扫描而不是索引扫描。

如果您不能使用该提示,或者由于某种原因它不起作用,还有其他方法可以帮助CBO在查询中使用集合。它正在为该集合实现Extensible Optimiser接口。它是由Adrian Billington在this article中写的,如何做到这一点。