1
CREATE TABLE WORK(
WorkerNo    NUMBER(10)  NOT NULL,
TotalSalary  NUMBER(10),
CONSTRAINT WORK_PKEY PRIMARY KEY (WorkerNo),

INSERT INTO WORK( 1, NULL );
INSERT INTO WORK( 2, NULL );

CREATE TABLE WorkSalary(
City VARCHAR2(30),
Postal VARCHAR2(30),
Salary NUMBER(9)    NOT NULL,
CONSTRAINT WorkSalary_PKEY PRIMARY KEY(City,Postal),

INSERT INTO WorkSalary('New York City', '123456', 5000);
INSERT INTO WorkSalary('Washington DC', '154876', 4500);
INSERT INTO WorkSalary('New Jersey', '458741', 3500);
INSERT INTO WorkSalary('Maryland', '487451', 2000);

CREATE TABLE WORKDONE(
WorkerNo NUMBER(10)     NOT NULL,
JobNo NUMBER(2)     NOT NULL,
City VARCHAR2(30)   NOT NULL,
Postal VARCHAR2(30) NOT NULL,
CONSTRAINT WORKDONE_PKEY PRIMARY KEY (WorkerNo, JobNo),
CONSTRAINT WORKDONE_FKEY1 FOREIGN KEY (WorkerNo) 
    REFERENCES WORK(WorkerNo),
CONSTRAINT WORKDONE_FKEY2 FOREIGN KEY (City)
    REFERENCES WorkSalary(City),
CONSTRAINT WORKDONE_FKEY3 FOREIGN KEY (Postal)
    REFERENCES WorkSalary(Postal) );

INSERT INTO WORKDONE VALUES( 1, 1, 'New York City', '123456');
INSERT INTO WORKDONE VALUES( 1, 2, 'Maryland', '487451');
INSERT INTO WORKDONE VALUES( 1, 3, 'New Jersey', '458741');
INSERT INTO WORKDONE VALUES( 2, 1, 'New Jersey', '458741');
INSERT INTO WORKDONE VALUES( 2, 2, 'New York City', '123456');
INSERT INTO WORKDONE VALUES( 2, 3, 'Washington DC', '154876');

我需要创建一个函数来获取工人在表 workdone 上所做的所有薪水的总和。例如,workerno 1 完成了 3 项工作,显示在 workdone 表上。我需要根据他工作的地方通过参考表薪来获得他所做的每项工作的薪水。然后我将把他所有的薪水加在一起,并将该工人的总薪水插入到具有列 totalsalary 的表工作中。

CREATE OR REPLACE FUNCTION SALARYCOUNT ( worker_no IN NUMBER ) RETURN NUMBER IS
wcity WORKDONE.City%TYPE;
wpostal WORKDONE.Postal%TYPE;
total NUMBER:
i INTEGER: = 1;
total_salary NUMBER;
wsalary NUMBER;


BEGIN 

SELECT COUNT(*)
INTO total
FROM WORKDONE
WHERE WorkerNo = worker_no;

WHILE i < total
LOOP

SELECT City,Postal INTO wcity,wpostal FROM WORKDONE WHERE WorkerNo = worker_no;

SELECT Salary INTO wsalary FROM WorkSalary WHERE wcity = City AND wpostal = Postal;

total_salary: =total_salary+wsalary ;

UPDATE WORK SET TotalSalary: = total_salary
WHERE WorkerNo = worker_no;

i: = i+1;

END LOOP;

RETURN(total_salary);

END SALARYCOUNT ;
/

创建函数时出现编译错误。我知道,如果我能够毫无错误地创建函数,那么我创建此函数的逻辑也可能不正确。请帮助我解决错误和代码的逻辑。我对此很陌生。

4

1 回答 1

2

首先,正如我在评论中所说,不要使用函数来执行 DML 语句(UPDATE/INSERT 等)。使用程序。函数是在 SQL 语句中调用的,选择时不能执行 DML 语句。

其次,您的外键WORKDONE不正确,您应该在同一个CITY外键中添加和:POSTAL

CONSTRAINT WORKDONE_FKEY2 FOREIGN KEY (City, Postal)
    REFERENCES WorkSalary(City, Postal) 

第三,也是对未来的更多说明,您的环境设置不正确;如果您在发布问题之前对此进行测试,将会很有帮助。

最后,绝对不需要使用函数来执行此操作。这一切都可以在一个MERGE语句中完成。使用单个 SQL 语句而不是 PL/SQL 几乎总是更有效。

 merge into work m
 using ( select wd.workerno, sum(ws.salary) as salary
           from workdone wd
           join worksalary ws
             on wd.city = ws.city
            and wd.postal = ws.postal
          group by wd.workerno ) u
    on (m.workerno = u.workerno)
  when matched then
update
   set m.totalsalary = u.salary;

这是一个用于演示的有效SQL Fiddle 。

于 2013-05-30T11:54:56.403 回答