在Oracle匿名块中获取更新或删除的记录
本文关键字:更新 删除 记录 获取 Oracle | 更新日期: 2023-09-27 18:19:39
我有一个连接到Oracle数据库的C#应用程序。我动态生成PL''SQL语句,并使用CommandType=Text
执行它们(我不使用SP)。
我的选择语句如下:
DECLARE
-- <declaring>
BEGIN
-- <some PL'SQL code>
OPEN :refCursor FOR SELECT * FROM tablename
-- <some PL'SQL code>
END;
在我的C#代码中,refCorsor是一个类型为Oracle.DataAccess.Client.OracleDbType.RefCursor
的参数,它使用输出方向添加到我的OracleCommand实例的参数中。
在ExecuteNonQuery调用返回后,我读取refCorsor参数以从select中获取数据。
我的问题是,当我想使用RETURNING BULK COLLECT INTO
子句在Oracle中获取已删除的记录时。
如您所知,在Oracle中,RETURNING BULK COLLECT INTO
子句可以用于在delete语句之后获取已删除记录的列。此子句将数据放入集合中。
DECLARE
TYPE RecordType IS RECORD("Id" INT,"Name" nvarchar2(50));
TYPE IdsTableType IS TABLE OF RecordType;
IdsName IdsTableType;
BEGIN
DELETE FROM "dbo"."AutoInt" WHERE "Name"='aaaa'
returning "Id","Name" BULK COLLECT INTO IdsName;
END;
问题是如何从C#代码中读取IdsName
的内容?
您可以在实际删除之前将要删除的记录集提取到光标中。当光标打开时,记录的状态将由Oracle维护。
DECLARE
-- <declaring>
BEGIN
-- <some PL'SQL code>
OPEN :refCursor FOR SELECT * FROM "AutoInt" WHERE "Name"='aaaa';
DELETE FROM "AutoInt" WHERE "Name"='aaaa';
-- <some PL'SQL code>
END;
其中一种方法是创建具有流水线功能的包-
CREATE OR REPLACE package pkg_records as
TYPE RecordType IS RECORD("Id" INT,"Name" nvarchar2(50));
TYPE IdsTableType IS TABLE OF RecordType;
function delete_auto_int RETURN IdsTableType PIPELINED;
END pkg_records;
/
CREATE OR REPLACE package body pkg_records as
function delete_auto_int(name_ in varchar2) RETURN IdsTableType PIPELINED is
PRAGMA AUTONOMOUS_TRANSACTION;
IdsName IdsTableType;
BEGIN
DELETE FROM "dbo"."AutoInt" WHERE "Name"= name_
returning "Id","Name" BULK COLLECT INTO IdsName;
commit;
if IdsName.count > 0 then
for i in IdsName.FIRST..IdsName.LAST loop
pipe ROW(IdsName(i));
end loop;
end if;
END;
END pkg_records;
/
然后只需使用简单的选择-
select * from table(pkg_records.delete_auto_int('aaaa'))