我有这个包,我在表中添加了一些值,这可行.... [/ p>
create or replace PACKAGE BODY DC_LOAN_PKG
IS
PROCEDURE loan_book
(
loan_id IN DC_LOAN_EVIDENCE.ID%type,
b_id IN DC_LOAN_EVIDENCE.BOOK_ID%type,
m_id IN DC_LOAN_EVIDENCE.MEMBER_ID%type,
d_ofl IN DC_LOAN_EVIDENCE.DATE_OF_LOAN%type)
IS
BEGIN
INSERT
INTO DC_LOAN_EVIDENCE
(
ID,
BOOK_ID,
MEMBER_ID,
DATE_OF_LOAN
)
VALUES
(
DC_SEQ.NEXTVAL,
b_id,
m_id,
SYSDATE
);
COMMIT;
END loan_book;
现在,我想编写程序return_book和extend_loan,我希望在返回书籍时获得DATE,并在扩展后获得新的贷款日期。我做错了什么?这是一个例子......
PROCEDURE return_book
(
b_id IN DC_LOAN_EVIDENCE.BOOK_ID%type,
m_id IN DC_LOAN_EVIDENCE.MEMBER_ID%type,
r_dat IN DC_LOAN_EVIDENCE.RETURN_DATE%type
)
IS
dStartDate DATE := TO_DATE('2014-12-23', 'YYYY-MM-DD');
dEndDate DATE := TO_DATE('2015-01-23', 'YYYY-MM-DD');
BEGIN
UPDATE DC_LOAN_EVIDENCE
SET RETURN_DATE =r_dat
WHERE MEMBER_ID =m_id
AND BOOK_ID =b_id
AND RETURN_DATE BETWEEN dStartDate AND dEndDate ;
COMMIT;
END return_book;
PROCEDURE extend_loan
(
b_id IN DC_LOAN_EVIDENCE.BOOK_ID%type,
m_id IN DC_LOAN_EVIDENCE.MEMBER_ID%type,
d_ofl IN DC_LOAN_EVIDENCE.DATE_OF_LOAN%type
)
IS
BEGIN
UPDATE DC_LOAN_EVIDENCE
SET DATE_OF_LOAN =d_ofl
WHERE MEMBER_ID =m_id
AND BOOK_ID =b_id;
COMMIT;
END extend_loan;
END DC_LOAN_PKG;
答案 0 :(得分:2)
您需要将内部过程保留在主过程的声明块中。
像 -
PROCEDURE return_book(
b_id IN DC_LOAN_EVIDENCE.BOOK_ID%type,
m_id IN DC_LOAN_EVIDENCE.MEMBER_ID%type,
r_dat IN DC_LOAN_EVIDENCE.RETURN_DATE%type )
IS
dStartDate DATE := TO_DATE('2014-12-23', 'YYYY-MM-DD');
dEndDate DATE := TO_DATE('2015-01-23', 'YYYY-MM-DD');
PROCEDURE extend_loan(
b_id IN DC_LOAN_EVIDENCE.BOOK_ID%type,
m_id IN DC_LOAN_EVIDENCE.MEMBER_ID%type,
d_ofl IN DC_LOAN_EVIDENCE.DATE_OF_LOAN%type )
IS
BEGIN
UPDATE DC_LOAN_EVIDENCE
SET DATE_OF_LOAN =d_ofl
WHERE MEMBER_ID =m_id
AND BOOK_ID =b_id;
COMMIT;
END extend_loan;
BEGIN
UPDATE DC_LOAN_EVIDENCE
SET RETURN_DATE =r_dat
WHERE MEMBER_ID =m_id
AND BOOK_ID =b_id
AND RETURN_DATE BETWEEN dStartDate AND dEndDate ;
COMMIT;
END return_book;
END DC_LOAN_PKG;
我会坚持你把它包在一个包里。使用这样的独立过程,您将引入依赖关系链。使用包可以避免这种情况。你可以实现封装,它有很多优点,就像Tom Kyte所说 -
打破依赖关系链(安装新的包体时没有级联失效 - 如果 你有程序调用程序 - 编译一个程序会使你的数据库失效)
支持封装 - 我将被允许编写MODULAR,易于理解的代码 - 而不是 然后是单一的,不可理解的程序
可测量地增加我的命名空间。包名称必须在模式中是唯一的,但我可以 跨包的许多程序具有相同的名称而不会发生冲突
支持重载
在您需要时支持会话变量
促进整体良好的编码技术,让你编写模块化的代码, 可理解的,逻辑上组合在一起....
编辑如果您的程序是独立的,那么您需要单独购买。
CREATE OR replace PACKAGE BODY dc_loan_pkg
IS
-- Procedure 1
PROCEDURE Loan_book(loan_id IN dc_loan_evidence.id%TYPE,
b_id IN dc_loan_evidence.book_id%TYPE,
m_id IN dc_loan_evidence.member_id%TYPE,
d_ofl IN dc_loan_evidence.date_of_loan%TYPE)
IS
BEGIN
INSERT INTO dc_loan_evidence
(id,
book_id,
member_id,
date_of_loan)
VALUES ( dc_seq.NEXTVAL,
b_id,
m_id,
SYSDATE );
COMMIT;
END loan_book;
-- Procedure 2
PROCEDURE Return_book (b_id IN dc_loan_evidence.book_id%TYPE,
m_id IN dc_loan_evidence.member_id%TYPE,
r_dat IN dc_loan_evidence.return_date%TYPE)
IS
dstartdate DATE := To_date('2014-12-23', 'YYYY-MM-DD');
denddate DATE := To_date('2015-01-23', 'YYYY-MM-DD');
BEGIN
UPDATE dc_loan_evidence
SET return_date = r_dat
WHERE member_id = m_id
AND book_id = b_id
AND return_date BETWEEN dstartdate AND denddate;
COMMIT;
END return_book;
-- Procedure 3
PROCEDURE Extend_loan(b_id IN dc_loan_evidence.book_id%TYPE,
m_id IN dc_loan_evidence.member_id%TYPE,
d_ofl IN dc_loan_evidence.date_of_loan%TYPE)
IS
BEGIN
UPDATE dc_loan_evidence
SET date_of_loan = d_ofl
WHERE member_id = m_id
AND book_id = b_id;
COMMIT;
END extend_loan;
END dc_loan_pkg;
/
答案 1 :(得分:0)
您的原始程序loan_book
有两个您不会使用的参数 - 无论您传递的是id
还是book_loan_date
都会被忽略,并被序列值替换为现在的日期。使用ID的序列是有道理的,但让用户传递他们自己的值会让人感到困惑,所以你应该删除那个参数。您是使用sysdate
还是贷款日期的传递值取决于您的业务规则,但目前这也是令人困惑的时刻。折衷方案可能是将该参数默认为sysdate
,因此可以在需要时覆盖它。
您的return_book
程序不会与loan_book
创建的任何记录相匹配,因为它会检查return_date
,这将是空的(除非您已经在此期间手动设置);如果你只能退还一次贷款,那检查似乎很奇怪。实质上,AND RETURN_DATE BETWEEN dStartDate AND dEndDate
将不匹配return_date
为空的任何行。
假设您传递了正确的图书和会员价值,您的extend_loan
程序似乎确实有效。
如果您没有看到date_of_loan
被扩展,那么您必须将错误的值传递给该过程。
但是,将书籍和成员传递给新程序意味着一本书只能借给一个成员一次。如果你想允许多次借用同一本书,你应该传递ID值,因为它(大概是!)是唯一的。也许return_date
中的return_book
过滤器实际上应该检查date_of_loan
是否是最近的,以试图解决这种歧义。传递ID会更好;明确地寻找未归还的书籍,和/或特定书籍/会员的最新贷款,在某种程度上也会起作用,但不那么健壮。
在程序中提交通常也被认为是不好的做法,让调用者决定是提交还是回滚更好。