在此SELECT语句中,Oracle存储过程需要一个INTO子句

时间:2014-02-03 15:49:15

标签: oracle10g

我正在进行下面提到的存储过程。

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;

执行存储过程时,我收到以下错误。

Error(11,1): PLS-00428: an INTO clause is expected in this SELECT statement

你能否为我提供这个问题的解决方案。在sql中执行相同的命令它工作正常但是在存储过程编译错误正在发生它意味着在存储过程INTO替换AS将给出相同的输出请澄清。< / p>

2 个答案:

答案 0 :(得分:4)

错误信息相当不言自明; PL/SQL version of a SELECT requires an INTO clause所以你的查询结果有所作为。您已经有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;

SELECT现在是INTO您的OUT参数,无论谁调用您的程序,其值都可以使用。

这仅在您的查询将始终返回一行时才有效。如果它没有返回任何内容,那么你将获得一个无数据发现的异常;如果它返回多行,你会得到太多行异常。并且您需要为查询返回的每列提供一个变量 - 在这种情况下只需要一个。您还可以声明一个局部变量(在ISBEGIN之间)来保存您将在过程中操作的临时值,但是您也不需要它。

当你编译你的程序时,它会说它编译时带有警告,因为语法错误。如果您是在SQL * Plus或SQL Developer中创建它,也可能是其他一些工具,您可以通过发出命令show errors立即看到错误,或者通过查询user_errors视图随时查看错误。当您调用该过程时,它无效并自动重新编译,这只会重新生成相同的错误,因为没有任何更改;那是你看到PLS-00428的消息。在编译时查找错误比在执行时等待重新编译更好。

顺便说一下,将固定值转换为表格所使用的数据类型通常会更好,而不是相反。当你这样做时:

  WHERE TO_CHAR(b1.msg_when_created,'YYYY-MM-DD') = in_start_date

...表中的每一列都必须将其msg_when_created DATE值转换为要与in_start_date字符串进行比较的字符串,这样会阻止该列的索引正在使用。最好这样做:

  WHERE b1.msg_when_created = TO_DATE(in_start_date, 'YYYY-MM-DD')

或者您的列有时间组件:

  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

让调用者将值转换为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

答案 1 :(得分:0)

使用功能

示例:select count(*) into cnt_length from Table