Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle:在游标声明中使用自定义函数_Oracle_Plsql - Fatal编程技术网

Oracle:在游标声明中使用自定义函数

Oracle:在游标声明中使用自定义函数,oracle,plsql,Oracle,Plsql,在一个过程中,我声明了一个游标。在游标声明中,我使用了datum\u naar\u dagdeel函数。函数本身确定一周中的某一天加上一天的某一部分,并将其转换为整数。请参阅代码摘要: ... CURSOR c_teamvoorkeuren IS SELECT DISTINCT a.seq_afpraak , a.datum_start , t.code , ks.code , ks.naam FROM afspraak a , tea

在一个过程中,我声明了一个游标。在游标声明中,我使用了
datum\u naar\u dagdeel
函数。函数本身确定一周中的某一天加上一天的某一部分,并将其转换为整数。请参阅代码摘要:

...
CURSOR c_teamvoorkeuren
IS
SELECT DISTINCT
       a.seq_afpraak
     , a.datum_start
     , t.code
     , ks.code
     , ks.naam
FROM afspraak a
   , team t
   , kamer_selectie ks
WHERE a.seq_aga_afspraak = p_seq_aga_afspraak
  AND t.seq_team = a.seq_team
  AND ks.seq_team = a.seq_team
  AND ks.dagdeel = instancename.datum_naar_dagdeel(a.datum_start)
...  
到目前为止,我发现:

  • GRANT EXECUTE
    已将该函数授予
    public
  • 过程中其他地方使用的其他自定义函数工作正常
  • 包含函数的select语句本身可以完美地工作。运行select part时,我得到了预期的结果
  • 当我用
    1
    替换
    instancename.datum\u naar\u dagdeel(a.date\u start)
    时,后面执行的for循环运行得非常好。由于
    1
    是给定预约功能的结果,我正在测试程序
  • 但是,当我使用函数而不是
    1
    时,for循环不会执行单个迭代。因此,我得出结论,是游标内部的函数组合导致了问题
在游标声明中使用自定义函数时,我是否在尝试做不可能的事情?如果它是自定义函数还是系统函数,会有区别吗


或者,我怀疑我可以构建一个在for循环本身内部使用函数的检查。当检查失败时,使用
continue
语句转到下一个迭代步骤。然而,这种解决方案感觉并不是很干净。

我试图复制你解释的内容;在这个例子中似乎是可以的

创建一个函数(我返回一个常量),连接为
mike
;将
执行
授予
公共

SQL> connect mike/lion
Connected.
SQL> create or replace function f_test
  2    return number
  3  is
  4  begin
  5    return 20;
  6  end;
  7  /

Function created.

SQL> grant execute on f_test to public;

Grant succeeded.
用户
scott
将在游标的
where
子句(第6行)中使用该函数:

所以-是的,它起作用了


如果函数返回例如
null
,则没有输出(当然没有):


您能否共享函数代码以及示例
afspraak.datum\u start
值?也许我们会注意到你没有注意到的东西。

找到了!(…最后)

显然,根据会话设置,一周中某一天的编号可能会有所不同。阅读本文的人现在可能已经猜到了,我的开发环境与生产环境有不同的默认设置。我怀疑这与
nls\u语言的设置有关

因此,代码没有“让我们匹配周一的预订设置”,而是尝试匹配周日不存在的预订

只有周一的测试数据,又不熟悉Oracle,可能也没什么帮助。知道吗,我确实对今天下午再次开始调试的每个人的反馈感到鼓舞,并感谢您的帮助

对于那些仍然感兴趣的人,下面我添加了函数的原始代码。在当前版本中,我修改了工作日编号,从周一的
1
开始

CREATE OR REPLACE 
FUNCTION instancename.datum_naar_dagdeel(datumtijd DATE)
  RETURN NUMBER
IS
  weekdag NUMBER := 0;
  dagdeel NUMBER := 0;
BEGIN
  
  SELECT TO_CHAR(datumtijd, 'D') INTO weekdag FROM dual;
  IF (weekdag = 2) THEN dagdeel := dagdeel + 1;  END IF;  -- Maandagochtend
  IF (weekdag = 3) THEN dagdeel := dagdeel + 3;  END IF;  -- Disndagochtend
  IF (weekdag = 4) THEN dagdeel := dagdeel + 5;  END IF;  -- Woensdagochtend
  IF (weekdag = 5) THEN dagdeel := dagdeel + 7;  END IF;  -- Donderdagochtend
  IF (weekdag = 6) THEN dagdeel := dagdeel + 9;  END IF;  -- Vrijdagochtend
  IF (weekdag = 7) THEN dagdeel := dagdeel + 11; END IF;  -- Zaterdagochtend
  
  -- Als de afspraak in de middag is, dan +1
  IF (TO_NUMBER(TO_CHAR(datumtijd, 'HH24')) >= 12) 
  THEN dagdeel := dagdeel + 1; 
  END IF; 
  
  RETURN dagdeel;
END;

-- Grants for Function
GRANT EXECUTE ON instancename.datum_naar_dagdeel TO PUBLIC;
GRANT DEBUG ON instancename.datum_naar_dagdeel TO PUBLIC;

注意:我在第一次发布后更改了此回复。我的最终发现显然与原始问题不符。

没有异常处理程序。。。至少现在还没有。我一定会试试你的建议。所以我猜你怀疑它应该能工作。正如我通常在C#Net或SQL Server上编程一样,可能需要几次尝试才能使其正常工作。考虑到欧洲的时间,它可能要等到星期天或星期一。一般来说,光标应该可以工作。可能提供函数的代码
datum\u naar\u dagdeel
,这似乎可以通过调试器轻松地清除。该函数可能不会返回预期值。
SQL> create or replace function f_test
  2    return number
  3  is
  4  begin
  5    return null;
  6  end;
  7  /

Function created.

SQL> connect scott/tiger
Connected.
SQL> exec p_test;

PL/SQL procedure successfully completed.

SQL>
CREATE OR REPLACE 
FUNCTION instancename.datum_naar_dagdeel(datumtijd DATE)
  RETURN NUMBER
IS
  weekdag NUMBER := 0;
  dagdeel NUMBER := 0;
BEGIN
  
  SELECT TO_CHAR(datumtijd, 'D') INTO weekdag FROM dual;
  IF (weekdag = 2) THEN dagdeel := dagdeel + 1;  END IF;  -- Maandagochtend
  IF (weekdag = 3) THEN dagdeel := dagdeel + 3;  END IF;  -- Disndagochtend
  IF (weekdag = 4) THEN dagdeel := dagdeel + 5;  END IF;  -- Woensdagochtend
  IF (weekdag = 5) THEN dagdeel := dagdeel + 7;  END IF;  -- Donderdagochtend
  IF (weekdag = 6) THEN dagdeel := dagdeel + 9;  END IF;  -- Vrijdagochtend
  IF (weekdag = 7) THEN dagdeel := dagdeel + 11; END IF;  -- Zaterdagochtend
  
  -- Als de afspraak in de middag is, dan +1
  IF (TO_NUMBER(TO_CHAR(datumtijd, 'HH24')) >= 12) 
  THEN dagdeel := dagdeel + 1; 
  END IF; 
  
  RETURN dagdeel;
END;

-- Grants for Function
GRANT EXECUTE ON instancename.datum_naar_dagdeel TO PUBLIC;
GRANT DEBUG ON instancename.datum_naar_dagdeel TO PUBLIC;