我有一个下面提到的存储过程.
create or replace
PROCEDURE example(
in_start_date IN VARCHAR2,
in_svc_provider IN a_message.msg_service_provider%type,sell OUT number)
IS
BEGIN SELECT COUNT(*) as sell
FROM a_message b1 WHERE TO_CHAR(b1.msg_when_created,'YYYY-MM-DD') = in_start_date
AND b1.msg_trans_type = 'SELL'
AND b1.msg_service_provider = in_svc_provider;
end;
Run Code Online (Sandbox Code Playgroud)
执行存储过程时,我收到以下错误.
Error(11,1): PLS-00428: an INTO clause is expected in this SELECT statement
Run Code Online (Sandbox Code Playgroud)
你能否为我提供这个问题的解决方案.在sql中执行相同的命令它工作正常但在存储过程编译错误正在发生它意味着在存储过程INTO替换AS将给出相同的输出请澄清.
错误消息是相当不言自明的;a 的PL /SQL 版本SELECT需要一个INTO子句,以便查询的结果有地方可去。您已经有一个OUT参数可以将值放入:
create or replace
PROCEDURE example(
in_start_date IN VARCHAR2,
in_svc_provider IN a_message.msg_service_provider%type,
sell OUT number)
IS
BEGIN
SELECT COUNT(*) INTO sell
FROM a_message b1
WHERE TO_CHAR(b1.msg_when_created,'YYYY-MM-DD') = in_start_date
AND b1.msg_trans_type = 'SELL'
AND b1.msg_service_provider = in_svc_provider;
end;
Run Code Online (Sandbox Code Playgroud)
SELECT现在是您INTO的OUT参数,并且任何调用您的过程的人都可以使用它的值。
仅当您的查询始终返回一行时,这才有效。如果它没有返回任何内容,那么您将得到一个未找到数据的异常;如果它返回多于一行,您将得到太多行异常。并且您需要为查询返回的每一列都有一个变量 - 在本例中只有一个变量。您还可以声明一个局部变量(在IS和 之间BEGIN)来保存将在过程中操作的临时值,但这里也不需要它。
当您编译过程时,它会说由于语法错误而编译时出现警告。如果您在 SQL*Plus 或 SQL Developer 以及其他一些工具中创建它,您可以通过发出命令立即看到错误show errors,或者随时通过查询user_errors视图来看到错误。当您调用该过程时,它是无效的并被自动重新编译,这只是重新生成相同的错误,因为没有任何更改;就在那时您看到了 PLS-00428 消息。最好在编译时查找错误,而不是在执行时等待重新编译。
顺便说一句,通常最好将固定值转换为表使用的数据类型,而不是相反。当你这样做时:
WHERE TO_CHAR(b1.msg_when_created,'YYYY-MM-DD') = in_start_date
Run Code Online (Sandbox Code Playgroud)
...表中的每一列都必须将其msg_when_created DATE值转换为字符串以便与该字符串进行比较in_start_date,这将阻止使用该列上的索引。最好这样做:
WHERE b1.msg_when_created = TO_DATE(in_start_date, 'YYYY-MM-DD')
Run Code Online (Sandbox Code Playgroud)
或者如果您的列有时间成分:
WHERE b1.msg_when_created >= TO_DATE(in_start_date, 'YYYY-MM-DD')
AND b1.msg_when_created < TO_DATE(in_start_date, 'YYYY-MM-DD') + INTERVAL '1' DAY
Run Code Online (Sandbox Code Playgroud)
让您的调用者将值转换为 a 会更好DATE,这样您就不必担心匹配传递的格式:
...
in_start_date IN a_message.msg_when_created%TYPE,
...
WHERE b1.msg_when_created >= TRUNC(in_start_date)
AND b1.msg_when_created < TRUNC(in_start_date) + INTERVAL '1' DAY
Run Code Online (Sandbox Code Playgroud)