Oracle-函数中的参数值为Null或空白

Oracle-函数中的参数值为Null或空白,oracle,performance,function,collections,bulk-operations,Oracle,Performance,Function,Collections,Bulk Operations,我试图从一个函数中获取结果,该函数进行查询、处理字段并返回集合 如果我对函数进行查询并单独执行,它将在大约10分钟后返回,具体取决于我输入的参数。如果我将相同的参数传递给函数,它将继续处理,45分钟后我将无法得到任何结果 查询之后,我只有几个if,用于检查零值或高于其他值的值 我认为问题在于我传递的一些参数为null或空白,这会导致查询崩溃。我的问题是: 我有一种类型: CREATE OR REPLACE TYPE TypeForFunction is OBJECT ( -- all m

我试图从一个函数中获取结果,该函数进行查询、处理字段并返回集合

如果我对函数进行查询并单独执行,它将在大约10分钟后返回,具体取决于我输入的参数。如果我将相同的参数传递给函数,它将继续处理,45分钟后我将无法得到任何结果

查询之后,我只有几个if,用于检查零值或高于其他值的值

我认为问题在于我传递的一些参数为null或空白,这会导致查询崩溃。我的问题是:

我有一种类型:

CREATE OR REPLACE TYPE TypeForFunction is OBJECT (
    -- all my fields here
 )
/
然后进行一次收集:

CREATE OR REPLACE TYPE TypeForFunctionTable AS
    TABLE OF TypeForFunction
/
然后我的函数是这样的:

CREATE OR REPLACE FUNCTION MyFunction
(
  /* here I have five parameters and in the case that the query crashes, 
     two of them I'm trying to pass blank or null */

  COL in varchar2, -- This I pass a valid value
  INDEX in number, -- same here
  REF in varchar2, -- This one I'm trying to pass Blank ('') or Null and i 
                      get no result no matter which one I pass.
  P in varchar2,   
  BLOQ in varchar2 -- Same null or blank here

) RETURN TypeForFunctionTable
IS  
  result_table TypeForFunctionTable;
  i integer := 0;
begin 
     select      
            TypeForFunction(

                /* Here I have some subquerys that I use the parameters null which 
                   I use the same way as parameter REF. Like: */ 
                
                and (MyTable.FieldP = P or P is null)
                and (MyTable.FielBloq = BLOQ or BLOQ is null)

            ) BULK COLLECT into result_table   
     from              
        myTables
        
     where
        -- here I have a clause like

        (MyTable.FieldREF = REF or REF is null)
     ;  
     For i in 1..result_table.count loop                 
         /* Here I have some if's, but nothing to crash the query like it happens. 
            Things like: */

         if MyVar > 0 then
            COL = REF;
            INDEX = INDEX + 100;


              
     end loop;        
     return result_table;     
 
end MyFunction;
/
CREATE OR REPLACE FUNCTION MyFunction
(
  /* here i have five parameters and in the case that the query crashes, 
     two of them i'm trying to pass blank or null */

  COL in varchar2, -- This I pass a valid value
  INDEX in number, -- same here
  REF in varchar2, -- This one I'm trying to pass Blank ('') or Null and i 
                      get no result no matter wich one I pass.
  P in varchar2,   
  BLOQ in varchar2 -- Same null or blank here

) RETURN TypeForFunctionTable
IS  
  result_table TypeForFunctionTable;
  i integer := 0;
  LOCAL_COL varchar2(4) := COL;
  LOCAL_REF varchar2(15) := REF;
  LOCAL_P varchar2(6) := P;
  LOCAL_BLOQ varchar2(1) :=;
要调用函数,我尝试:

select * from table(MyFunction('59', 1, '', 'IV18', ''));
还可以尝试:

select * from table(MyFunction('59', 1, Null, 'IV18', Null));
无论如何,我得到了相同的结果,函数在45分钟后不会返回或给出任何错误


有没有更好的方法来处理我可能传递或不传递值的参数?

我无法使查询更快。事实证明,这个查询在不久前就已经被优化了,它返回了下一个季度的生产赌注,基于我工作的公司上一个季度的生产赌注(这是巴西的一家女装厂),所以它很重

但是后来我写了一个过程来做三个简单的更新,我遇到了同样的问题,它一直挂起,没有给我任何运行过程的结果,但是单独运行的更新查询工作得很好

我开始搜索并找到了这个答案:

这是一个SQL Server anwser,但随后我开始搜索该问题是否也影响到Oracle,我发现了以下帖子:

所以我在函数和过程中都声明了局部变量,这些变量是否收到了参数

现在我的函数如下所示:

CREATE OR REPLACE FUNCTION MyFunction
(
  /* here I have five parameters and in the case that the query crashes, 
     two of them I'm trying to pass blank or null */

  COL in varchar2, -- This I pass a valid value
  INDEX in number, -- same here
  REF in varchar2, -- This one I'm trying to pass Blank ('') or Null and i 
                      get no result no matter which one I pass.
  P in varchar2,   
  BLOQ in varchar2 -- Same null or blank here

) RETURN TypeForFunctionTable
IS  
  result_table TypeForFunctionTable;
  i integer := 0;
begin 
     select      
            TypeForFunction(

                /* Here I have some subquerys that I use the parameters null which 
                   I use the same way as parameter REF. Like: */ 
                
                and (MyTable.FieldP = P or P is null)
                and (MyTable.FielBloq = BLOQ or BLOQ is null)

            ) BULK COLLECT into result_table   
     from              
        myTables
        
     where
        -- here I have a clause like

        (MyTable.FieldREF = REF or REF is null)
     ;  
     For i in 1..result_table.count loop                 
         /* Here I have some if's, but nothing to crash the query like it happens. 
            Things like: */

         if MyVar > 0 then
            COL = REF;
            INDEX = INDEX + 100;


              
     end loop;        
     return result_table;     
 
end MyFunction;
/
CREATE OR REPLACE FUNCTION MyFunction
(
  /* here i have five parameters and in the case that the query crashes, 
     two of them i'm trying to pass blank or null */

  COL in varchar2, -- This I pass a valid value
  INDEX in number, -- same here
  REF in varchar2, -- This one I'm trying to pass Blank ('') or Null and i 
                      get no result no matter wich one I pass.
  P in varchar2,   
  BLOQ in varchar2 -- Same null or blank here

) RETURN TypeForFunctionTable
IS  
  result_table TypeForFunctionTable;
  i integer := 0;
  LOCAL_COL varchar2(4) := COL;
  LOCAL_REF varchar2(15) := REF;
  LOCAL_P varchar2(6) := P;
  LOCAL_BLOQ varchar2(1) :=;
我在所有查询中都使用了“局部”变量,效果很好。解决了这个问题。因为我的名声,我无法感谢那个在原始帖子上发表评论的家伙,但我非常感谢


也感谢你的回复

此函数返回多少条记录?该函数使用批量收集并将所有记录放入在内存中创建的集合中。如果有很多记录,那么它可能会耗尽内存,并交换磁盘上的内存表-这总是很慢。我不确定此函数的作用是什么,为什么要从函数中选择,而不是使用简单的选择直接从表中选择,这一定很慢。我不清楚
null
vs
'
问题与此问题有什么关系。函数具有的
varchar2
参数没有区别。问题到底是什么?查询或多或少返回一组7k条记录。我这样做是因为我需要处理它返回的列,我认为这是最好的方法。还认为它是null参数,因为如果run传递了所有有效值,它就可以完美地运行。Firebird可以处理这么多的数据,我不敢相信oracle不能处理。当然oracle可以处理大量的数据。但是,编写性能差的查询很容易,尤其是刚接触Oracle时。您要求我们提供优化提示,但没有向我们显示您的实现的任何细节。所以我们不能给你任何实际的建议。我们可以说,几乎可以肯定,您所经历的性能低下是由于您编写代码的方式造成的。如果您想发布实际的程序、查询和数据结构,那么我们可能会更有帮助。我询问了变量,因为传递或不传递值时的行为不同。但是,如果使用批量收集和慢速查询可能会导致问题,我可以尝试对其进行优化。