在 Oracle 中设置存储过程
Setting up a stored procedure in Oracle
我正在努力创建一个存储过程,该过程需要输入 ID 以及开始和结束日期,然后 returns 属于该范围内的行程。我一直在查看 oracle 文档,我认为我已经接近了,但是还遇到了一些错误:
CREATE or replace PROCEDURE chg_per_aircraft
(p_aircraft_id IN RCC_AIRCRAFT.aircraft_id,
p_start_date IN date,
p_end_date IN date,
p_ttl_chg_per_acft OUT INTEGER)
AS
BEGIN
SELECT RCC_AIRCRAFT.aircraft_id,
SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg
INTO
p_aircraft_id,
p_ttl_chg_per_acft
FROM RCC_AIRCRAFT
full join RCC_CHARTER
on RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id
left join RCC_MODEL
on RCC_MODEL.model_code = RCC_AIRCRAFT.model_code
Where RCC_CHARTER.trip_date > p_start_date and RCC_CHARTER.trip_date < p_end_date
group by RCC_AIRCRAFT.aircraft_id;
SYS.DBMS_OUTPUT.PUT_LINE(ttl_chg);
end;
你的第一个错误是参数定义:
p_aircraft_id IN RCC_AIRCRAFT.aircraft_id
应该是
p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE
但是您正在 selecting INTO p_aircraft_id
,它被声明为 IN 参数,因此您无法将其设置为新值。那是你想传入的变量,还是你想输出的值?它作为调用者随日期一起提供的东西更有意义,但是您需要将它用作 select 语句中的过滤器。如果有不止一个飞机 ID - 可能如果它仅受日期限制 - 那么你会得到多个结果,无论如何这将是一个 too_many_rows 错误。
您的输出将仅对设置为处理它的会话可见,因此调用者这样做可能更有意义;但无论如何应该是:
DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft);
... 因为 ttl_chg
仅作为列别名存在,而不是 PL/SQL 变量。
如果您要传递飞机 ID,您可能需要这样的东西:
CREATE or replace PROCEDURE chg_per_aircraft
(p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE,
p_start_date IN date,
p_end_date IN date,
p_ttl_chg_per_acft OUT INTEGER)
AS
BEGIN
SELECT SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg
INTO p_ttl_chg_per_acft
FROM RCC_AIRCRAFT
JOIN RCC_CHARTER
ON RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id
JOIN RCC_MODEL
ON RCC_MODEL.model_code = RCC_AIRCRAFT.model_code
WHERE RCC_CHARTER.trip_date > p_start_date
AND RCC_CHARTER.trip_date < p_end_date
AND RCC_AIRCRAFT.aircraft_id = p_aircraft_id
GROUP BY RCC_AIRCRAFT.aircraft_id;
-- just to debug!
DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft);
END;
/
我也更改为内部联接,因为将它们设为外部联接似乎没有用。这作为函数比过程更有意义;尽管在存储程序中包装单个查询可能是不必要的——尽管这看起来像一个赋值。
我正在努力创建一个存储过程,该过程需要输入 ID 以及开始和结束日期,然后 returns 属于该范围内的行程。我一直在查看 oracle 文档,我认为我已经接近了,但是还遇到了一些错误:
CREATE or replace PROCEDURE chg_per_aircraft
(p_aircraft_id IN RCC_AIRCRAFT.aircraft_id,
p_start_date IN date,
p_end_date IN date,
p_ttl_chg_per_acft OUT INTEGER)
AS
BEGIN
SELECT RCC_AIRCRAFT.aircraft_id,
SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg
INTO
p_aircraft_id,
p_ttl_chg_per_acft
FROM RCC_AIRCRAFT
full join RCC_CHARTER
on RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id
left join RCC_MODEL
on RCC_MODEL.model_code = RCC_AIRCRAFT.model_code
Where RCC_CHARTER.trip_date > p_start_date and RCC_CHARTER.trip_date < p_end_date
group by RCC_AIRCRAFT.aircraft_id;
SYS.DBMS_OUTPUT.PUT_LINE(ttl_chg);
end;
你的第一个错误是参数定义:
p_aircraft_id IN RCC_AIRCRAFT.aircraft_id
应该是
p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE
但是您正在 selecting INTO p_aircraft_id
,它被声明为 IN 参数,因此您无法将其设置为新值。那是你想传入的变量,还是你想输出的值?它作为调用者随日期一起提供的东西更有意义,但是您需要将它用作 select 语句中的过滤器。如果有不止一个飞机 ID - 可能如果它仅受日期限制 - 那么你会得到多个结果,无论如何这将是一个 too_many_rows 错误。
您的输出将仅对设置为处理它的会话可见,因此调用者这样做可能更有意义;但无论如何应该是:
DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft);
... 因为 ttl_chg
仅作为列别名存在,而不是 PL/SQL 变量。
如果您要传递飞机 ID,您可能需要这样的东西:
CREATE or replace PROCEDURE chg_per_aircraft
(p_aircraft_id IN RCC_AIRCRAFT.aircraft_id%TYPE,
p_start_date IN date,
p_end_date IN date,
p_ttl_chg_per_acft OUT INTEGER)
AS
BEGIN
SELECT SUM(RCC_CHARTER.distance * RCC_MODEL.charge_per_mile) ttl_chg
INTO p_ttl_chg_per_acft
FROM RCC_AIRCRAFT
JOIN RCC_CHARTER
ON RCC_CHARTER.aircraft_id = RCC_AIRCRAFT.aircraft_id
JOIN RCC_MODEL
ON RCC_MODEL.model_code = RCC_AIRCRAFT.model_code
WHERE RCC_CHARTER.trip_date > p_start_date
AND RCC_CHARTER.trip_date < p_end_date
AND RCC_AIRCRAFT.aircraft_id = p_aircraft_id
GROUP BY RCC_AIRCRAFT.aircraft_id;
-- just to debug!
DBMS_OUTPUT.PUT_LINE(p_ttl_chg_per_acft);
END;
/
我也更改为内部联接,因为将它们设为外部联接似乎没有用。这作为函数比过程更有意义;尽管在存储程序中包装单个查询可能是不必要的——尽管这看起来像一个赋值。