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
时,后面执行的for循环运行得非常好。由于instancename.datum\u naar\u dagdeel(a.date\u start)
是给定预约功能的结果,我正在测试程序1
- 但是,当我使用函数而不是
时,for循环不会执行单个迭代。因此,我得出结论,是游标内部的函数组合导致了问题1
或者,我怀疑我可以构建一个在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;