使用过程自动将数据插入表中

时间:2018-11-22 21:03:36

标签: oracle stored-procedures plsql constraints

我想问你一个简单的问题,但由于我是SQL的初学者,所以我无法解决。

我的任务是:通过将行插入到BankStats2中,将初始数据输入BankStats2 包含分支名称以及贷款中有多少贷款 该分支名称的表格。

desc BankStats2
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 BRANCHNAME                                NOT NULL VARCHAR2(20)
 NUMBEROFLOANS                                      NUMBER(38)

desc Loan
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 CUSTOMERNAME                                       CHAR(20)
 BRANCHNAME                                         CHAR(20)
 AMOUNT                                             NUMBER(38)
 LOANNUMBER                                NOT NULL NUMBER(38)

 select branchName,count(customerName) from Loan group by branchName;

BRANCHNAME           COUNT(CUSTOMERNAME)
-------------------- -------------------
Yorkshire                              3
RoyalBank                              1
Midlands                               3

基本上,我想将此信息插入BankStats2表中,而我想到的方法是创建一个程序,该程序将在下面显示。

CREATE OR REPLACE PROCEDURE PopulateBankStats AS
CURSOR someLoanRows IS
SELECT branchName,COUNT(customerName) FROM loan GROUP BY branchName;
aBranchNameRow loan.branchName%TYPE;
numberOfLoans INT;
BEGIN
OPEN someLoanRows;
LOOP
FETCH someLoanRows INTO aBranchNameRow, numberOfLoans;
INSERT INTO BankStats2 VALUES (aBranchNameRow,numberOfLoans);
EXIT WHEN someLoanRows%NOTFOUND;
END LOOP;
CLOSE someLoanRows;
END;
/

但是执行它会给我以下错误:

ERROR at line 1:
ORA-00001: unique constraint (N0757934.SYS_C0034405) violated
ORA-06512: at "N0757934.POPULATEBANKSTATS", line 10
ORA-06512: at line 1

任何帮助将不胜感激。谢谢您的时间!

2 个答案:

答案 0 :(得分:0)

此插入失败:INSERT INTO BankStats2 VALUES (aBranchNameRow,numberOfLoans);
由于错误:ORA-00001: unique constraint (N0757934.SYS_C0034405) violated

这意味着在表BankStats2的某些列上创建了一个唯一约束。

为了找到具有唯一约束的列,请运行以下查询:

select * from USER_IND_COLUMNS where index_name = 'SYS_C0034405';

您的过程正在尝试插入表中已存在的具有此列值的记录。

答案 1 :(得分:0)

看看INSERT语句。

您的程序正在做的是正是这个插入语句

INSERT INTO BankStats2 (BRANCHNAME,NUMBEROFLOANS)
SELECT branchName,COUNT(customerName) FROM loan GROUP BY branchName;

始终最好使用SQL语句(如果可能的话),而不是PL / SQL游标循环logik-搜索Tom Kyte's“逐行-逐个缓慢”以寻找外植体。

即使您不惜一切代价使用程序,也请在本规程中使用此INSERT

您的例外意味着您尝试插入表BRANCHNAME中已经存在的列BankStats2的值。

这可能是由于意外或系统性问题。

如果发生意外,只需清除数据,即使用BankStats2表中的相应键删除行。

此查询返回两个表中都存在的值

select BRANCHNAME from BankStats2 
intersect 
select branchName  FROM loan;

如果要系统地避免插入重复行,请在INSERT语句中添加以下逻辑:

INSERT INTO BankStats2 (BRANCHNAME,NUMBEROFLOANS)
SELECT branchName,COUNT(customerName) 
FROM loan
WHERE branchName IS NOT NULL 
and branchName NOT IN (select BRANCHNAME from BankStats2)
GROUP BY branchName;

请注意,SELECT使用NOT IN (subquery)排除了目标表中具有该值的行。

请注意,我正在处理您的下一个可能的问题BRANCHNAME中的列BankStats2不可为空,而loan中的不可为空(即可能包含NULL),因此您将无法插入带有NULL的行到表BankStats2中。因此,我用branchName IS NOT NULL谓词排除了这些行。

如果要使用UPDATE logik处理现有键,请检查MERGE语句。