我尝试创建一个只能在3月份根据系统日期执行的存储过程。以下是此类代码的新闻:
CREATE PROCEDURE sp_time_window (
p_sales_ID in sales.sales_ID%TYPE,
p_product in sales.product%TYPE,
p_unitCost in sales.unitcost%TYPE,
p_quantity in sales.quantity%TYPE)
IS BEGIN
DECLAR v_date varchar(3)
BEGIN
SELECT TO_CHAR(sysdate,'MM') into v_date from duaL
IF (v_date in ('MAR')) THEN
INSERT INTO sales (sales_ID, product, unitcost, quantity) values
(p_sales_ID, p_ product, p_unitCost, p_quantity);
ENDIF;
END;
END;
/
ORACLE给了我这个错误:
LINE/COL ERROR
-------- ---------------------------------------------------
14/2 PL/SQL: SQL Statement ignored
16/5 PL/SQL: ORA-00933: SQL command not properly ended
请帮助
答案 0 :(得分:2)
你有一个BEGIN / END的冗余图层,以及各种拼写错误,其中一些我认为你刚刚介绍了创建问题,比如DECLAR
而不是DECLARE
。但是可能会出现错误的第一件事是在dual
之后缺少分号。
SELECT TO_CHAR(sysdate,'MM') into v_date from duaL;
您可以直接将月份值分配给变量,而无需选择双重选择:
v_date := TO_CHAR(sysdate,'MM');
...但是你已经定义为varchar2(3)并且后来寻找MAR,那个格式掩码应该是MON而不是MM。但是,无论如何使用数字更安全,否则您需要确保您的会话是英语。您的变量应该是合适的类型。
您在p_ product
和ENDIF
而不是END IF
中也有空格,但这些空格可能不在您的真实代码中。
你可以减少你拥有的东西:
CREATE OR REPLACE PROCEDURE sp_time_window (
p_sales_ID in sales.sales_ID%TYPE,
p_product in sales.product%TYPE,
p_unitCost in sales.unitcost%TYPE,
p_quantity in sales.quantity%TYPE)
AS
BEGIN
IF extract(month from sysdate) = 3 THEN
INSERT INTO sales (sales_ID, product, unitcost, quantity)
VALUES (p_sales_ID, p_product, p_unitCost, p_quantity);
END IF;
END;
/
extract(month from sysdate)
获取该日期的月份编号,因此您可以检查该数字是否为3,而不是字符串。如果在v_date
子句中进行提取,则也不需要本地IF
变量。
默默地忽略插入看起来很奇怪,因为调用者不会知道是否会发生这种情况。这不会阻止程序外的插入。在这种情况下,可能适合使用触发器,如果月份数不是3,则会引发异常。