Tôi là một chút gỉ trên lingo trỏ của tôi trong PL/SQL. Có ai biết điều này không?Sự khác biệt giữa con trỏ rõ ràng và tiềm ẩn trong Oracle là gì?
Trả lời
Con trỏ ẩn là một con trỏ được tạo ra "tự động" cho bạn bởi Oracle khi bạn thực hiện truy vấn. Nó là đơn giản để mã, nhưng bị từ
- không hiệu quả (tiêu chuẩn ANSI xác định rằng nó phải lấy hai lần để kiểm tra nếu có nhiều hơn một hồ sơ)
- dễ bị tổn thương đến sai sót dữ liệu (nếu bạn đã bao giờ có được hai hàng , nó đặt ra một ngoại lệ TOO_MANY_ROWS)
Ví dụ
SELECT col INTO var FROM table WHERE something;
một con trỏ rõ ràng là một trong những bạn tạo ra. Nó cần nhiều mã hơn, nhưng cho phép kiểm soát nhiều hơn - ví dụ, bạn chỉ có thể mở tìm nạp nếu bạn chỉ muốn bản ghi đầu tiên và không quan tâm nếu có những người khác.
Ví dụ
DECLARE
CURSOR cur IS SELECT col FROM table WHERE something;
BEGIN
OPEN cur;
FETCH cur INTO var;
CLOSE cur;
END;
Câu trả lời này rất tuyệt vời, rất nhiều chi tiết và đoạn trích. Cảm ơn –
Câu trả lời này là tốt, và tôi sẽ bỏ phiếu, ngoại trừ việc nó nói rằng các con trỏ tiềm ẩn không hiệu quả, điều này là sai - chúng thường hiệu quả hơn trong việc tìm kiếm con trỏ rõ ràng, trong trường hợp chúng thích hợp! –
-1 vì lý do không hiệu quả là sai vì một số phiên bản 7.x và lỗ hổng đối với lỗi dữ liệu là một điều tốt trong quan điểm của tôi. Nếu bạn mong đợi một hàng, nhưng bạn nhận được hai, nó là rất mong muốn mà bạn được cảnh báo bởi ngoại lệ TOO_MANY_ROWS. –
Một con trỏ rõ ràng là một trong những bạn khai báo, như:
CURSOR my_cursor IS
SELECT table_name FROM USER_TABLES
Một con trỏ ngầm là một trong những tạo ra để hỗ trợ bất kỳ SQL trong dòng bạn viết (hoặc tĩnh hoặc động).
Một con trỏ rõ ràng được định nghĩa như vậy trong một khối khai:
DECLARE
CURSOR cur IS
SELECT columns FROM table WHERE condition;
BEGIN
...
một con trỏ ngầm được implented trực tiếp trong một khối mã:
...
BEGIN
SELECT columns INTO variables FROM table where condition;
END;
...
Với con trỏ rõ ràng, bạn có toàn quyền điều khiển cách truy cập thông tin trong cơ sở dữ liệu. Bạn quyết định khi nào MỞ con trỏ, khi tới FETCH bản ghi từ con trỏ (và do đó từ bảng hoặc bảng trong câu lệnh SELECT của con trỏ) có bao nhiêu bản ghi để tìm nạp, và khi nào ĐÓNG con trỏ. Thông tin về trạng thái hiện tại của con trỏ có sẵn thông qua việc kiểm tra thuộc tính con trỏ.
Xem http://www.unix.com.ua/orelly/oracle/prog2/ch06_03.htm để biết chi tiết.
Mỗi câu lệnh SQL được thực hiện bởi cơ sở dữ liệu Oracle có một con trỏ liên kết với nó, mà là một khu vực làm việc riêng để lưu trữ xử lý thông tin. Các con trỏ ngầm được tạo ngầm bởi máy chủ Oracle cho tất cả các câu lệnh DML và SELECT.
Bạn có thể khai báo và sử dụng các con trỏ rõ ràng để đặt tên vùng làm việc riêng và truy cập thông tin được lưu trữ trong khối chương trình của bạn.
Rõ ràng ...
con trỏ foo được chọn * từ blah; bắt đầu mở lấy lối ra khi con trỏ gần yada yada yada
không sử dụng chúng, sử dụng tiềm ẩn
con trỏ foo là select * from blah;
cho n trong vòng lặp foo x = n.some_column cuối vòng lặp
Tôi nghĩ rằng bạn thậm chí có thể làm điều này
cho n trong (select * from blah) loop ...
Dính vào tiềm ẩn, họ tự đóng, họ dễ đọc hơn, họ làm cho cuộc sống dễ dàng.
Những ngày này con trỏ tiềm ẩn hiệu quả hơn con trỏ rõ ràng.
http://www.oracle.com/technology/oramag/oracle/04-sep/o54plsql.html
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688
Google là bạn của bạn: http://docstore.mik.ua/orelly/oracle/prog2/ch06_03.htm
PL/SQL phát hành một con trỏ ngầm bất cứ khi nào bạn thực hiện một câu lệnh SQL trực tiếp trong mã của bạn, miễn là điều đó Mã số không sử dụng con trỏ rõ ràng . Nó được gọi là con trỏ "" ẩn " " do bạn, nhà phát triển, làm không khai báo rõ ràng con trỏ cho câu lệnh SQL .
Một con trỏ rõ ràng là một câu lệnh SELECT được định nghĩa một cách rõ ràng trong phần khai báo mã của bạn, và trong quá trình này, chỉ định một tên . Không có con số rõ ràng nào như một con trỏ rõ ràng cho các câu lệnh UPDATE, DELETE, và INSERT.
vẫn còn tốt hơn;) http://www.google.com/search?hl=vi&q=difference+between+an+explicit+cursor+and+an+implicit+cursor+site:stackoverflow.com – msw
Để trả lời câu hỏi đầu tiên. Trực tiếp từ Oracle documentation
Một con trỏ là một con trỏ đến một khu vực SQL tin lưu trữ thông tin về chế biến một SELECT cụ thể hoặc DML tuyên bố.
Con trỏ là cửa sổ được chọn trên bảng Oracle, điều này có nghĩa là một nhóm bản ghi có trong bảng Oracle và đáp ứng các điều kiện nhất định. Một con trỏ cũng có thể SELECT tất cả nội dung của một bảng. Với một con trỏ, bạn có thể thao tác với các cột Oracle, đánh dấu chúng trong kết quả. Một ví dụ về con trỏ ngầm như sau:
BEGIN
DECLARE
CURSOR C1
IS
SELECT DROPPED_CALLS FROM ALARM_UMTS;
C1_REC C1%ROWTYPE;
BEGIN
FOR C1_REC IN C1
LOOP
DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
END LOOP;
END;
END;
/
Với CHO ... LOOP ... END LOOP bạn mở và đóng con trỏ authomatically, khi các hồ sơ của con trỏ đã được tất cả các phân tích.
Một ví dụ về con trỏ rõ ràng như sau:
BEGIN
DECLARE
CURSOR C1
IS
SELECT DROPPED_CALLS FROM ALARM_UMTS;
C1_REC C1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO c1_rec;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('DROPPED CALLS: ' || C1_REC.DROPPED_CALLS);
END LOOP;
CLOSE c1;
END;
END;
/
Trong con trỏ rõ ràng bạn mở và đóng con trỏ một cách rõ ràng, kiểm tra sự hiện diện của hồ sơ và nêu một tình trạng thoát.
Con trỏ ngầm định chỉ trả về một bản ghi và được gọi tự động. Tuy nhiên, con trỏ rõ ràng được gọi là thủ công và có thể trả về nhiều hơn một bản ghi.
1.CURSOR: Khi PLSQL phát hành câu lệnh sql, nó tạo vùng làm việc riêng để phân tích cú pháp & thực thi câu lệnh sql được gọi là con trỏ.
2.IMPLICIT: Khi bất kỳ khối PL/SQLexecutable nào có thể phát hành câu lệnh sql. PL/SQL tạo con trỏ ngầm và quản lý tự động có nghĩa là ngụ ý mở & đóng diễn ra. Nó được sử dụng khi câu lệnh sql trả lại chỉ một hàng. Nó có 4 thuộc tính SQL% ROWCOUNT, SQL% FOUND, SQL% NOTFOUND, SQL% ISOPEN.
3.EXPLICIT: Nó được tạo ra & do lập trình viên quản lý. Cần mở mọi thời gian rõ ràng, tìm nạp & đóng. Nó được sử dụng khi câu lệnh sql trả về nhiều hàng. Nó cũng có 4 thuộc tính CUR_NAME% ROWCOUNT, CUR_NAME% FOUND, CUR_NAME% NOTFOUND, CUR_NAME% ISOPEN. Nó xử lý một số hàng bằng cách sử dụng vòng lặp. Người lập trình có thể chuyển tham số cho con trỏ rõ ràng.
- Ví dụ: Explicit Cursor
declare
cursor emp_cursor
is
select id,name,salary,dept_id
from employees;
v_id employees.id%type;
v_name employees.name%type;
v_salary employees.salary%type;
v_dept_id employees.dept_id%type;
begin
open emp_cursor;
loop
fetch emp_cursor into v_id,v_name,v_salary,v_dept_id;
exit when emp_cursor%notfound;
dbms_output.put_line(v_id||', '||v_name||', '||v_salary||','||v_dept_id);
end loop;
close emp_cursor;
end;
con trỏ ngầm đòi hỏi bộ nhớ đệm nặc danh.
Có thể dễ dàng truy cập các con trỏ rõ ràng bằng cách sử dụng tên của chúng. Chúng được lưu trữ trong không gian bộ nhớ do người dùng xác định thay vì được lưu trữ trong bộ nhớ đệm ẩn danh và do đó có thể dễ dàng truy cập sau đó.
Tôi biết đây là một câu hỏi cũ, tuy nhiên, tôi nghĩ sẽ tốt hơn nếu thêm một ví dụ thực tế để hiển thị sự khác biệt giữa hai từ quan điểm về hiệu suất.
Từ quan điểm hiệu suất, con trỏ ngầm sẽ nhanh hơn.
Hãy xem sự khác biệt về hiệu năng giữa hai:
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 l_loops NUMBER := 100000;
3 l_dummy dual.dummy%TYPE;
4 l_start NUMBER;
5
6 CURSOR c_dual IS
7 SELECT dummy
8 FROM dual;
9 BEGIN
10 l_start := DBMS_UTILITY.get_time;
11
12 FOR i IN 1 .. l_loops LOOP
13 OPEN c_dual;
14 FETCH c_dual
15 INTO l_dummy;
16 CLOSE c_dual;
17 END LOOP;
18
19 DBMS_OUTPUT.put_line('Explicit: ' ||
20 (DBMS_UTILITY.get_time - l_start) || ' hsecs');
21
22 l_start := DBMS_UTILITY.get_time;
23
24 FOR i IN 1 .. l_loops LOOP
25 SELECT dummy
26 INTO l_dummy
27 FROM dual;
28 END LOOP;
29
30 DBMS_OUTPUT.put_line('Implicit: ' ||
31 (DBMS_UTILITY.get_time - l_start) || ' hsecs');
32 END;
33/
Explicit: 332 hsecs
Implicit: 176 hsecs
PL/SQL procedure successfully completed.
Vì vậy, một sự khác biệt đáng kể là rõ ràng.
Ví dụ khác here.
Như đã nêu trong các câu trả lời khác, các con trỏ tiềm ẩn dễ sử dụng hơn và ít bị lỗi hơn.
Và Implicit vs. Explicit Cursors in Oracle PL/SQL cho thấy rằng con trỏ tiềm ẩn nhanh hơn hai lần so với con trỏ rõ ràng.
Thật kỳ lạ mà không ai đã chưa được đề cập Implicit FOR LOOP Cursor:
begin
for cur in (
select t.id from parent_trx pt inner join trx t on pt.nested_id = t.id
where t.started_at > sysdate - 31 and t.finished_at is null and t.extended_code is null
)
loop
update trx set finished_at=sysdate, extended_code = -1 where id = cur.id;
update parent_trx set result_code = -1 where nested_id = cur.id;
end loop cur;
end;
Một ví dụ khác về SO: PL/SQL FOR LOOP IMPLICIT CURSOR.
Đó là cách ngắn hơn biểu mẫu rõ ràng.
Điều này cũng cung cấp giải pháp thay thế tốt cho updating multiple tables from CTE.
Mọi thứ khác về chức năng? –
trùng lặp chính xác: http://stackoverflow.com/questions/74010/what-is-the-difference-between-explicit-and-implicit-cursors-in-oracle – msw
"trùng lặp" mà bạn đang đề cập đến không giải thích phần đầu tiên của câu hỏi: "con trỏ là gì". –