请找到这个问题的解决方案。 (在 PL SQL 中)--------

please find the solution of this problem. ( in PL SQL ) --------

我正在做一个作业,最后一个问题表明我调用了问题 2 中的过程和问题 3 中的函数,然后将它们放在插入子句中(问题 4)。

  1. Write a PL/SQL Code for an anonymous block to do the following (in package):

a) Get the doctor name for a given doctor id (read from keyboard) using a function [FunGetDoctorName].

b) Get the department name for a given department id (read from keyboard) using a procedure [ProGetepartmentName].

c) Insert the doctor name and department name (which you got from the function and

procedure) by including serial number and current date into the visitings table.

将答案放入(包)

这是我的table代码:

CREATE TABLE DEPT(
DeptNo      NUMBER PRIMARY KEY,
DeptName    VARCHAR2(30) NOT NULL);

CREATE TABLE DOCTORS(
DoctorID    NUMBER PRIMARY KEY,
DoctorNAME  VARCHAR2(30) NOT NULL,
DeptNo      NUMBER REFERENCES DEPT(DEPTNO),
Salary      NUMBER NOT NULL);

CREATE TABLE VISITINGS(
SlNo        NUMBER PRIMARY KEY,
DoctorName  VARCHAR2(30),
DepartmentName  VARCHAR2(30),
VisitDate   DATE);

INSERT INTO DEPT VALUES(10,'ENT');
INSERT INTO DEPT VALUES(20,'Orthopedic');
INSERT INTO DEPT VALUES(30,'Cardiology');
INSERT INTO DEPT VALUES(40,'Neurology');

INSERT INTO DOCTORS VALUES(101,'Abheer',20,2550);
INSERT INTO DOCTORS VALUES(102,'Zuwaina',10,2175);
INSERT INTO DOCTORS VALUES(103,'Sara',30,1985);
INSERT INTO DOCTORS VALUES(104,'Fatma',20,2200);
INSERT INTO DOCTORS VALUES(105,'Laila',10,2600);

INSERT INTO VISITINGS VALUES(1,'Sara','Cardiology','10-Nov-19');
INSERT INTO VISITINGS VALUES(2,'Abheer','Orthopedic','11-Nov-19');

我的函数

create or replace function FunGetDoctorName(Docid number) return varchar2 is
docname DOCTORS.DoctorName%type;
Begin
select DoctorName into docname from DOCTORS where DoctorID = Docid;
return docname;
End ;
/

我的程序

create or replace procedure ProGetDepartmentName is
depname dept.DeptName%type;
Begin
select DeptName into depname from dept where DeptNo =10;
dbms_output.put_line(depname);
End ;
/ 

这是问题所在:

Create or replace package pkg1 is 
Function FunGetDoctorName(Docid Number) return varchar2 ;
procedure ProGetDepartmentName(DeptNo NUMBER);
end pkg1;
/
CREATE OR REPLACE PACKAGE BODY pkg1 AS

FUNCTION FunGetDoctorName(Docid Number)
RETURN varchar2 IS
   docname DOCTORS.DoctorName%type;
BEGIN
   select DoctorName into docname from DOCTORS where DoctorID = Docid;
return docname ;
END;
PROCEDURE ProGetDepartmentName(DeptNo NUMBER) IS
depname dept.DeptName%type;
BEGIN
 Select DeptName into depname from dept where DeptNo=10; 
dbms_output.put_line(depname) ;
END;
END pkg1 ;
/
declare
ProGetDepartmentName
(:DeptNo in dept.DeptNO%type,
 depname in dept.DeptName%type) 
FunGetDoctorName
(:Docid in DOCTORS.DoctorID%type ,
docname in DOCTORS.DoctorName%type);
docname varchar2(30);
depname varchar2(30);
Docid number;
serial number;
is 
Begin
dbms_output.put_line('Department Name: '||depname);
select count(slno) into serial from visitings;
serial :=serial+1;
insert into visitings(slno,doctorname,departmentname,visitdate) values(serial,docname,depname,sysdate);
End;
/

我不断收到错误消息:

SP2-0552:未声明绑定变量“DOCID”。

首先,你的程序必须有一个in和一个out参数,这样你才能传递deptno并得到deptname作为输出。

procedure ProGetDepartmentName(p_depnum number,P_depname out varchar)
is
Begin
  select DeptName into P_depname from dept where DeptNo = p_depnum;
  dbms_output.put_line(p_depnum);
End ;
/ 

在您的 pl/sql 块中,您可以使用替换变量从键盘获取输入,如下所示:

declare
  V_DeptNo dept.DeptNO%type := &dept_no
  V_deptname in dept.DeptName%type;
  V_Docid in DOCTORS.DoctorID%type := &doc_id;
is 
Begin
  Pkg1.ProGetDepartmentName(v_deptno,  v_deptname);
  dbms_output.put_line('Department Name: '|| v_deptname);
  insert into visitings(slno,doctorname,departmentname,visitdate) 
    values((select count(slno) + 1 from visitings),FunGetDoctorName(v_docid),v_deptname,sysdate);
End;
/

:

  1. 您应该使用 sequence.
  2. 而不是从 table 中获取计数并将其加一到 slno
  3. procedurefunction中,使用exception block来优雅地处理找不到行或找到多条记录或任何其他问题。
  4. 在插入到table的同时,还应该使用exceprion block来优雅地处理问题。 (在您的情况下,由于 count(slno) + 1 逻辑,它是必需的,因为它可以将相同的编号分配给同时执行的不同会话,这会导致主键违规)