Я выполняю задание, и в последнем вопросе говорится, что я вызываю процедуру из вопроса 2 и функцию из вопроса 3, а затем помещаю их в предложение вставки (вопрос 4).
- Напишите код PL/SQL для анонимного блока, чтобы сделать следующее (в пакете):
а) Получить имя врача для данного идентификатора врача (читать с клавиатуры) используя функцию [FunGetDoctorName].
б) Получить название отдела для заданного идентификатора отдела (читать из клавиатура) с помощью процедуры [ProGetepartmentName].
c) Вставьте имя врача и название отделения (которое вы получили из функция и
процедуры) путем включения серийного номера и текущей даты в таблица посещений.
поместите ответ в (Пакет)
это мои коды таблиц:
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" не объявлена.
Кроме того, дизайн вашей таблицы несовершенен. В вашей таблице VISITINGS вместо DoctorName и DepartmentName у вас должны быть DoctorID и DepNo с внешними ключами обратно к DOCTORS и DEPT.
Прежде всего, ваша процедура должна иметь один параметр 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;
/
Примечание:
slno
, вы должны использовать sequence
.procedure
и function
используйте exception block
, чтобы изящно обработать не найденную строку или несколько найденных записей или любые другие проблемы.exceprion block
для изящной обработки проблем. (В вашем случае это необходимо из-за логики count(slno) + 1
, поскольку он может назначать один и тот же номер разным сеансам, выполняющимся одновременно, что может привести к нарушению первичного ключа)извините, он все еще не работает.... Мне нужно добавить эту часть в пакет. большое спасибо .
Чтобы присвоить значение переменной с помощью функции, это что-то вроде
doctorName := myfunction(DocId)
. Чтобы назначить с помощью процедуры, ей нужен параметрout
, тогда будетmyprocedure(inDeptId, OutDeptName);