Oracle stored procedure an INTO clause is expected in this SELECT statement

不问归期 提交于 2020-01-14 09:22:29

问题


I am having a stored procedure mentioned below.

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;

While executing the stored procedure I am getting following error.

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

Can you please provide me the resolution for this issue.while executing the same command in sql it is working fine but in stored procedure compilation error is occurring it means in stored procedure INTO replacing AS will give the same output please clarify.


回答1:


The error message is fairly self-explanatory; the PL/SQL version of a SELECT requires an INTO clause so the result of your query has somewhere to go. You already have an OUT parameter to put the value into:

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;

The SELECT is now INTO your OUT parameter, and its value will be available to whoever calls your procedure.

This only works if your query will always return exactly one row. If it doesn't return anything then you'll get a no-data-found exception; if it returns more than one row you'll get a too-many-rows exception. And you need to have a variable for each column your query returns - only one in this case. You can also declare a local variable (between IS and BEGIN) to hold temporary values that you will manipulate within the procedure, but you don't need that here either.

When you compiled your procedure it would have said it compiled with warnings, because of that syntax error. If you created it in SQL*Plus or SQL Developer, and maybe some other tools, you could have seen the error straight away by issuing the command show errors, or at any time by querying the user_errors view. When you called the procedure it was invalid and was automatically recompiled, which just regenerated the same error as nothing had changed; that's when you saw the PLS-00428 message. It's better to look for errors at compile time than wait for recompilation at execution time.

Incidentally, it's generally better to convert a fixed value into the data type used by your table, rather than the other way round. When you do this:

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

... every column in your table has to have its msg_when_created DATE value converted to a string to be compared to the in_start_date string, which would prevent an index on that column being used. It's preferable to do:

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

or if your column has a time component:

  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

It would be even better to make your caller convert the value to a DATE so you don't have to worry about matching a passed format:

...
    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



回答2:


use into function

example: select count(*) into cnt_length from Table



来源:https://stackoverflow.com/questions/21531670/oracle-stored-procedure-an-into-clause-is-expected-in-this-select-statement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!