Bạn phải chọn vào thứ gì đó. Nếu bạn không thì truy vấn thậm chí không được thực thi (mặc dù nó đã được phân tích cú pháp).
create or replace procedure select_procedure
as
l_name student.name%TYPE;
l_surname student.name%TYPE;
begin
execute immediate
'select name, surname
from student
where id_student = 1'
into l_name, l_surname;
end;
/
Tuy nhiên, không theo thứ tự cụ thể:(a) bạn nên sử dụng các biến ràng buộc thay vì có giá trị theo nghĩa đen 1 được nhúng trong câu lệnh động; (b) điều này không cần phải năng động chút nào; và (c) người gọi sẽ không thể nhìn thấy các giá trị được trả về bởi truy vấn - trừ khi bạn chọn vào OUT
thay vào đó, hoặc hiển thị chúng bằng dbms_output()
(mặc dù điều đó thực sự chỉ nên được sử dụng để gỡ lỗi vì bạn không thể kiểm soát liệu máy khách có hiển thị nó hay không).
Vì vậy, bạn có thể làm:
create or replace procedure select_procedure
as
l_name student.name%TYPE;
l_surname student.name%TYPE;
begin
select name, surname
into l_name, l_surname
from student
where id_student = 1;
dbms_output.put_line('name=' || l_name ||', surname=' || l_surname);
end;
/
hoặc
create or replace procedure select_procedure (
p_name OUT student.name%TYPE,
p_surname OUT student.name%TYPE
)
as
begin
select name, surname
into p_name, p_surname
from student
where id_student = 1;
end;
/
và yêu cầu người gọi của bạn chuyển các tên biến riêng để điền vào, sau đó làm bất cứ điều gì họ cần với những tên đó. Người gọi thường cũng sẽ chuyển ID bạn đang tìm kiếm, vì vậy bạn không có 1 mã cứng.
Tuy nhiên, có vẻ như một thủ tục không thực sự là cơ chế tốt nhất cho việc này.
Ngoài ra, sử dụng select ... into
(tĩnh hoặc động) sẽ lỗi nếu truy vấn trả về không hàng hoặc nhiều hơn một hàng. Nó sẽ chỉ hoạt động nếu có chính xác một hàng được trả về. Một con trỏ sẽ xử lý bất kỳ số hàng nào - nhưng trừ khi bạn chỉ in kết quả (như @Jayanth hiển thị), thay vào đó, bạn cần chuyển con trỏ trở lại người gọi. Bạn có thể thực hiện bulk collect into
thay vào đó là một bộ sưu tập, nhưng bạn vẫn phải làm gì đó với bộ sưu tập đó.