所以我对一些PL SQL语句有点麻烦。基本上我正在尝试创建一个程序来检查当插入新元组时,程序检查在同一日期内没有同一个人的另一个合同,即。新合同的日期与另一合同的日期不重叠。
以下是代码:
CREATE OR REPLACE PROCEDURE dateOrder
(name IN VARCHAR2, start IN DATE, end IN DATE)
IS
x number;
y number;
BEGIN
CREATE OR REPLACE VIEW PersonContracts AS
SELECT * FROM ContractInfo WHERE HasContract=name;
SELECT COUNT(*) INTO x FROM PersonContracts
WHERE start BETWEEN date_from AND date_to;
SELECT COUNT(*) INTO y from PersonContracts
WHERE end BETWEEN date_from AND date_to;
IF x > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
IF Y > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
END dateOrder;
/
BEGIN
dateOrder("John Smith", "08-oct-2014", "12-oct-2014");
END;
我在有或没有视图的情况下尝试了它,但我更愿意保留视图(如果可能)。我只是PL的新人!
答案 0 :(得分:1)
您无法在使用DDL的过程中创建VIEW(您必须使用EXECUTE IMMEDIATE来执行此操作)。
我更喜欢直接设置SELECT语句的WHERE-Clause:
CREATE OR REPLACE PROCEDURE dateOrder (name IN VARCHAR2, start IN DATE, end IN DATE)
IS
x number;
y number;
BEGIN
SELECT COUNT(*) INTO x FROM ContractInfo WHERE HasContract=name
AND start BETWEEN date_from AND date_to;
SELECT COUNT(*) INTO y from ContractInfo WHERE HasContract=name
AND end BETWEEN date_from AND date_to;
IF x > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
IF Y > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
END dateOrder;
/
BEGIN
dateOrder("John Smith", "08-oct-2014", "12-oct-2014");
END;
答案 1 :(得分:1)
所以有些事情在你的程序中是行不通的。以此为推荐而非解决方案:
检查出来:
CREATE OR REPLACE PROCEDURE dateOrder
(name IN VARCHAR2, xstart IN DATE, xend IN DATE)
IS
x number;
y number;
BEGIN
execute immediate (
'CREATE OR REPLACE VIEW PersonContracts AS
SELECT * FROM ContractInfo ....'
);
-- that won't work, because the PersonContracts will be not there at compile time.
SELECT COUNT(*) INTO x FROM PersonContracts
WHERE start BETWEEN date_from AND date_to;
SELECT COUNT(*) INTO y from PersonContracts
WHERE end BETWEEN date_from AND date_to;
IF x > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
IF Y > 0 THEN
dbms_output.put_line("overlaps.");
END IF;
END dateOrder;
BEGIN
dateOrder("John Smith", "08-oct-2014", "12-oct-2014");
END;
答案 2 :(得分:0)
即使允许,视图也是不必要的。您只想检查HasContract
值等于name
参数的行。好的,按照您的意愿编写查询,然后将HasContract = name
添加到where
子句中。不要过度思考简单的解决方案。
此外,您可以在一个查询中找到所需内容。您要捕获的条件是,开始和停止日期定义的间隔与任何现有的开始和停止日期之间是否存在任何重叠。虽然我们可以煞费苦心地列出可能导致重叠的所有可能的安排,但让我们看看不导致重叠的两种安排。
或者,在等式中e1 <= s2 or s1 >= e2
。一点布尔魔术,我们可以反转为e1 > s2 and s1 < e2
。这为我们提供了简化的查询:
select COUNT(*) into y
from ContractInfo
where HasContract = name
and p_end > date_from
and p_start < date_to;
如果此查询返回任何非零答案,则会在某处出现重叠。一个简单的查询,一个检查后。容易。