Database 使用pl/sql查找表中的多个值并在不存在时插入的过程
我有这个表和这个关系:单位-->费用-->角色Database 使用pl/sql查找表中的多个值并在不存在时插入的过程,database,oracle,plsql,cursor,procedure,Database,Oracle,Plsql,Cursor,Procedure,我有这个表和这个关系:单位-->费用-->角色 UNIT_CODE | CHARGE_CODE | ROLE_CODE 0101010001 | 9023409 | AZAAAA 0102010002 | 8023409 | AXAAAB 0103010003 | 7023409 | ACAAAC 0104010004 | 6023409 | AVAAA
UNIT_CODE | CHARGE_CODE | ROLE_CODE
0101010001 | 9023409 | AZAAAA
0102010002 | 8023409 | AXAAAB
0103010003 | 7023409 | ACAAAC
0104010004 | 6023409 | AVAAAV
0101010001 | 5023409 | NEWROL
0102010002 | 4023409 | AZAAAA
此表几乎有2000行/行
因此,情况如下:
我必须为特定的90单元代码插入一个特定的角色\u COD(NEWROL
)。但这个角色适用于特定的单位负责人
示例:我必须为该单元插入角色代码=新角色
,0101010001
和该费用5023409
- 因此,我必须检查:
- 如果单位
已经存在对0101010001
- 如果单位/费用
0101010001/5023409
关系已经存在对
0101010001/5023409/NEWROL
对0102010002/4023409
0102010002
已经存在对0102010002/4023409
关系已经存在对
0102010002/4023409/NEWROL
已经存在没有我必须检查90个单位,我需要一个程序来收取
单位代码
和费用
进行验证,必要时插入角色代码
。这里是一个纯SQL解决方案:
insert into your_table t
select unit_code, charge_code, 'NEWROL'
from
( select unit_code, charge_code from your_table
where (unit_code = '0101010001' and charge_code = 5023409)
or (unit_code = '0102010002' and charge_code = 4023409)
minus
select unit_code, charge_code from your_table
where role_code = 'NEWROL' )
/
子查询返回一组没有角色的(单位代码、费用代码)
。如果确实需要存储过程,可以调整上限WHERE子句以使用PL/SQL参数
下面是一个将此查询过程化的解决方案。它使用SQL类型传递目标(单位代码、费用代码)
对:
create or replace type unit_charge_t as object
(unit_code varchar2(10), charge_code number);
/
create or replace type unit_charge_nt as table of unit_charge_t;
/
这是一个简单的概念证明。您需要添加日志记录、异常处理等
create or replace procedure ins_your_table
(p_recs in unit_charge_nt
, p_new_role in your_table.role_code%type := 'NEWROL')
as
begin
insert into your_table t
select unit_code, charge_code, 'NEWROL'
from
( select unit_code, charge_code from your_table
where (unit_code, charge_code) in (select * from table(p_recs))
minus
select unit_code, charge_code from your_table
where role_code = 'NEWROL' );
dbms_output.put_line('inserted records = '||sql%rowcount);
end ins_your_table;
/
调用示例:
SQL> set serveroutput on
SQL> declare
2 tgt_rows unit_charge_nt
3 := unit_charge_nt ( unit_charge_t('0101010001', 5023409)
4 , unit_charge_t('0102010002', 4023409) );
5 begin
6 ins_your_table(tgt_rows);
7 end;
8 /
inserted records = 1
PL/SQL procedure successfully completed.
SQL>
最大的挑战仍然是将目标密钥从文档中获取到数据库中。我个人会选择一个程序员的文本编辑器,比如记事本++。这使得使用regex search'n'replace将值列表转换为这些类型赋值变得轻而易举
search: ([0-9]+)\t([0-9]+)
replace: unit_charge_t\('\1', \z\)
另一种界面是使用外部表,将.docx
更改为.csv
文件
有许多可能的解决办法;哪个最合适取决于您的情况的特殊性。我使用以下查询解决了这个问题:
CREATE OR REPLACE PROCEDURE my_procedure
(in_unit_code IN table_1.unit_code%TYPE,
in_charge_code IN table_1.charge_code%TYPE,
in_role_code IN table_1.role_code%TYPE)
AS
BEGIN
trace('my_procedure_p', 'a', 'Role Insert starting');
INSERT INTO table_1 (
unit_code,
charge_code,
role_code
) values (
in_unit_code,
in_charge_code,
in_role_code
);
trace('my_procedure_p', 'a',
'It is inserted correctly. ROLE: ' || in_role_code ||
', UNIT: ' || in_unit_code ||
', CHARGE: ' || in_charge_code ||
' Date: ' || SYSDATE);
COMMIT;
--Note: If the insert is successful i COMMIT, but if records are duplicates i captured with this exception.
EXCEPTION
WHEN dup_val_on_index THEN
ptraza('my_procedure_p', 'a',
'Attention, ROLE: ' || in_role_code ||
' It is already in the table UNIT: ' || in_unit_code ||
', CHARGE: ' || in_charge_code);
END my_procedure;
我这样打电话:
BEGIN
my_procedure('0000000004','CHARGE01','ROLECODE01');
my_procedure('0000000003','CHARGE02','ROLECODE01');
my_procedure('0000000002','CHARGE00','ROLECODE03');
my_procedure('0000000001','CHARGE00','ROLECODE03');
END;
这90个单位代码
,费用
组合的值来自哪里?另一张桌子?不,他们来自同一张桌子。但是我已经确定了90号单位代码,它们是我必须检查的特定费用@APCUNIT\u代码不是唯一的<代码>0101010001
重复了您是对的@MahendarMahi,但在此表中,我们将找到相同的单位代码
,差异代码费用
和角色代码
。这是一个关系表。所以,我想知道,当我运行它时,我是否可以制作一个程序,使用单位代码,充电\u代码
,并测试他们是否有NEWROL
,如果它没有插入表
。这是个好主意,但这样我必须把90个条件放在哪里?您知道运行获取值的过程吗我定义的单位和功能是什么@APC@spikeTJ-我问过你如何存储这些值,但你没有给出实际答案。所以我不确定你希望我提出什么建议。如果这是一个一次性的练习,您可以将WHERE子句克隆编辑90次。如果你想让这是可重用的,你需要提供更多的细节。是的,我希望这是可重用的。我有一个unit\u code
和相应的code\u费用
列表,他们必须在其中插入NEWROL
。我正在尝试执行一个过程,为相应的单元代码、费用代码插入角色
。抱歉,如果我解释得不好@APC。显然我没有很好地解释自己。你有一张单子。您希望对该列表中的每个条目执行检查和更新。但是这个列表是什么格式的呢?该列表上的条目是否以某种方式存储在数据库中,还是在数据库之外(在电子表格、电子邮件、您的头部)?我所说的可重复使用是指将来某个时候,你是否需要为不同的(单位代码、费用代码)对列表重复这个练习?好的,我在.docx文件中有这个列表。所以我想要程序,因为这样我只需要复制deunit\u code
和charge
,如果我要调用程序,并将其作为参数传递。是的,也许我必须为不同的列表重复一遍,但始终使用以下参数:UNIT\u code,CHARGE\u code
@APC