如何在plsql块中执行删除语句并在过程中调用它
Posted
技术标签:
【中文标题】如何在plsql块中执行删除语句并在过程中调用它【英文标题】:how to execute delete statement inside plsql block and call it in a procedure 【发布时间】:2019-11-21 10:48:11 【问题描述】:我已经写在 pl sql 块下面并尝试创建一个程序。但是我收到警告并且无法执行该程序。
如果我遗漏了什么,请提出建议\
如果这个问题重复,请告诉我,因为我无法获得确切的参考链接
create or replace PROCEDURE EmployeeProc
IS
BEGIN
delete from Employeetable where EmplId in (
select EmployeeId FROM EmployeeMstrTbl where JoiningDate between to_date('2019-01-01','YYYY-MM-DD') and to_date('2019-02-28','YYYY-MM-DD'));
commit;
DBMS_OUTPUT.PUT_LINE('Deleted '||SQL%ROWCOUNT ||' records from Employeetable');
END;
Error: Object Invalid
【问题讨论】:
你能告诉我们编译时引发的实际错误吗? @Tejash .. 感谢您的回复。我收到错误:“程序无效”,在创建程序时我收到警告.. 可以发show error
,告诉我们你得到了什么。
【参考方案1】:
尝试使用光标
CREATE OR REPLACE PROCEDURE EMPLOYEEPROC IS
CURSOR C1 IS
SELECT EMPLOYEEID
FROM EMPLOYEEMSTRTBL
WHERE JOININGDATE BETWEEN TO_DATE('2019-01-01','YYYY-MM-DD') AND TO_DATE('2019-02-28','YYYY-MM-DD'));
BEGIN
FOR I IN C1 LOOP
DELETE FROM EMPLOYEETABLE
WHERE EMPLID=I.EMPLOYEEID;
END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('DELETED '||SQL%ROWCOUNT ||' RECORDS FROM EMPLOYEETABLE');
END;
【讨论】:
【参考方案2】:您的代码运行良好。
CREATE TABLE Employeetable
(
EmplId NUMBER
);
CREATE TABLE EmployeeMstrTbl
(
EmployeeId NUMBER,
JoiningDate DATE
);
CREATE OR REPLACE PROCEDURE EmployeeProc
IS
BEGIN
DELETE FROM Employeetable
WHERE EmplId IN
(SELECT EmployeeId
FROM EmployeeMstrTbl
WHERE JoiningDate BETWEEN TO_DATE ('2019-01-01',
'YYYY-MM-DD')
AND TO_DATE ('2019-02-28',
'YYYY-MM-DD'));
COMMIT;
DBMS_OUTPUT.PUT_LINE (
'Deleted ' || SQL%ROWCOUNT || ' records from Employeetable');
END;
EXEC EmployeeProc;
DROP TABLE Employeetable;
DROP TABLE EmployeeMstrTbl;
DROP PROCEDURE EmployeeProc;
脚本输出:
Table created.
Table created.
Procedure created.
PL/SQL procedure successfully completed.
Table dropped.
Table dropped.
Procedure dropped.
DBMS 输出:
Deleted 0 records from Employeetable
也许您在表名、列名或类似名称中有拼写错误。
我建议你先尝试执行你的删除语句,看看它是否有效。
【讨论】:
【参考方案3】:不确定您是否打错了某些内容,或者是否与您的设置方式有关。但即使它是一个错误的类型并且它可以工作,它也不是很好,所以做一个循环。
i = 0;
FOR r in (select * FROM EmployeeMstrTbl where JoiningDate between to_date('2019-01-01','YYYY-MM-DD') and to_date('2019-02-28','YYYY-MM-DD'))
LOOP
DELETE FROM Employeetable where EmplId = r.EmployeeId;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Deleted '|| i ||' records from Employeetable');
因为这会起作用,更重要的是,它更容易理解。由于代码的大小几乎从来都不是问题,因此保持代码简短和简略已经变得不那么重要了,但保持其易于理解非常重要,以便将来可以维护。
【讨论】:
@TineO .. 非常感谢您的回复.. 但查询挂起,无法删除数据 @Tejash 是的,当涉及到大量数据时,性能可能很重要。但随着计算机能力的进步,性能优化变得不那么重要了。如果您知道自己正在处理大型数据集,那么您可能希望在工作时优化性能,但是尝试从一开始就优化所有代码以提高性能是一个坏主意,因为它很可能需要更长的时间并且可能可读性较差。而且性能优化甚至可能没有太大区别。 @Ravi 那么请在控制台中作为一个未命名的过程进行尝试。首先尝试使用 sql 查询来获取要删除的 ID,然后在简单的删除中使用其中的一个,如果这两个工作都尝试将其全部放入循环中,然后在其中添加您想要的任何其他内容。将其运行到最短的可重现示例,找出问题出现的确切位置,然后返回给我,我会尽力提供帮助。 抱歉,我不同意这个切换到逐行删除的建议。如果删除大量行,这可能会导致巨大的性能问题。使用面向集合的 DELETE 或使用 PL/SQL 的 FORALL 语句来启用 DELETE 的批量处理。 @TimeO,对于少量的行,确定 FORALL 是不必要的,但也不会担心单个面向集合的删除。最重要的是,Ravi 并没有真正给我们足够的信息来正确诊断和建议。以上是关于如何在plsql块中执行删除语句并在过程中调用它的主要内容,如果未能解决你的问题,请参考以下文章
如何使用plsql导出oracle数据建表语句,存储过程,视图.以及表中数据
plsql调用oracle存储过程有输入参数和输出参数 sql语句怎么写如题 谢谢了