2013-02-22 14 views
5

Với PL/SQL sẽ có một tình huống, ví dụ trong trường hợp ngoại lệ, trong đó một con trỏ ngầm sẽ không đóng được?Một con trỏ tiềm ẩn có bao giờ không đóng được trong PL/SQL không?

Tôi hiểu rằng một con trỏ tiềm ẩn phải tự đóng sau khi sử dụng, nhưng chỉ muốn biết nếu có trường hợp này có thể không xảy ra, và nếu điều này là có thể, loại xử lý nào sẽ là tốt ý kiến.

+0

Nó có thể hữu ích nếu bạn xác định chính xác ý bạn là gì bởi "con trỏ ẩn". Bạn có nghĩa là một vòng lặp FOR bằng cách sử dụng SQL, hoặc DML? –

Trả lời

1

Khi COMMIT or ROLLBACK thất bại con trỏ sẽ không tự động đóng
Đó là khuyến cáo sử dụng dưới đường khi sử dụng con trỏ:

-- before using the cursor 
    IF your_cursor %ISOPEN THEN 
     CLOSE your_cursor; 
    END IF; 
    OPEN your_cursor; 

-- after using the cursor 
     CLOSE your_cursor; 
-- when exception 
    IF your_cursor %ISOPEN THEN 
     CLOSE your_cursor; 
    END IF; 
+0

Vì vậy, trong trường hợp này nếu COMMIT hoặc ROLLBACK không thành công, liệu có ngoại lệ không? Nếu đúng như vậy, sẽ không tốt hơn cho một cái gì đó như: NGOẠI TRỪ KHI KHÁC THÊM NẾU MyCursor% IS_OPEN THEN ĐÓNG MyCursor; END IF; – user2100452

+0

Có, tôi chỉnh sửa câu trả lời. –

+4

Nhưng đó là sử dụng con trỏ * rõ ràng *. OP đang nói về * implicit * cursors ('cho foo_rec trong (select * from foo) loop ...'). Trong trường hợp đó không có biến con trỏ và không có cách nào để kiểm tra nó với '% isopen'. –

0

tôi sẽ cho rằng bạn đang nói về con trỏ ngầm, tức là một câu lệnh SELECT INTO ... hoặc một câu lệnh DML được thực hiện trong một khối PL/SQL trái với một vòng lặp FOR.

Như với con trỏ rõ ràng, các con trỏ tiềm ẩn có các thuộc tính; . Bạn có thể sử dụng SQL%NOTFOUND (thay vì CURSOR_NAME%NOTFOUND ví dụ

Để trích dẫn từ 11.1 documentation trên con trỏ ngầm thuộc tính cho SQL%ISOPEN:

Luôn luôn trả về FALSE, bởi vì cơ sở dữ liệu đóng con trỏ SQL tự động sau khi thực hiện liên quan của nó Câu lệnh SQL

Điều này nên, tôi tin, được thực hiện để có nghĩa là các con trỏ sẽ bị đóng sau khi thực thi, cho dù có ngoại lệ hay không. ted do một ngoại lệ vẫn là một câu lệnh SQL được thi hành.

Lý do đã bị xóa khỏi the 11.2 documentation.

SQL% ISOPEN luôn có giá trị FALSE.

Nó dường như đã được bổ sung vào chapter on implicit cursors thay vì:

SQL% ISOpen luôn trả về FALSE, bởi vì một con trỏ ngầm luôn đóng sau khi tuyên bố chạy liên quan của nó.

Cho dù con trỏ đóng hay không không thực sự quan trọng do câu trả lời cho câu hỏi cuối cùng của bạn, "loại khắc phục nào sẽ là ý tưởng hay".. Để trích dẫn từ cùng một chương:

Bạn không thể kiểm soát con trỏ ẩn, nhưng bạn có thể lấy thông tin từ các thuộc tính của nó.

Vì vậy, không. Không thể khắc phục được; không thể đóng một con trỏ được mở một cách rõ ràng.

Một điều bạn có thể muốn thử nghiệm là liệu bạn có thể nâng cao ORA-0100: Maximum open cursors exceeded bằng cách sử dụng các con trỏ ngầm hoàn toàn vì đây là hậu quả tồi tệ nhất mà tôi có thể nghĩ đến.

+0

Theo hướng dẫn bạn có thể ** không ** tham chiếu 'SQL ISOPEN' http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/cursor_for_loop_statement.htm#CJABCJEA:" * Tuy nhiên, vì select_statement không phải là một câu lệnh độc lập, con trỏ ẩn là nội bộ - bạn không thể tham chiếu nó với tên SQL * " –

1

Hãy xác định "con trỏ ẩn" như một câu lệnh SELECT được thực hiện trong vòng lặp FOR.

Nhìn vào nó từ một quan điểm thực tế - bất kể có hay không một con trỏ tiềm ẩn được mở ra, câu hỏi quan trọng là "Bạn có thể làm gì với nó?". Theo hiểu biết tốt nhất của tôi, câu trả lời cho câu hỏi đó là "Không có gì". Bạn không có một biến con trỏ để làm việc với, không có cách nào (mà tôi biết) để truy cập vào con trỏ ngầm, và do đó bạn thực sự không thể ảnh hưởng đến nó.

Có hai việc bạn có thể làm. Đầu tiên là hoàn toàn tránh việc sử dụng các con trỏ ngầm. Chỉ sử dụng con trỏ rõ ràng, đi qua tất cả các bước mở, tìm nạp, đóng, v.v. Điều này cho bạn mức kiểm soát tối đa. Nếu bạn đang vào loại điều này, đi cho nó.

Mặt khác, bạn có thể sử dụng các con trỏ ngầm và không lo lắng. Tôi tốt với không đáng lo ngại. :-) Nghiêm túc, mặc dù, con trỏ ngầm là IMO cực kỳ tốt hơn so với con trỏ rõ ràng. Có ít mã để viết, và do đó ít mã để vít lên. Hệ thống có thể, trong một số trường hợp, tối ưu hóa việc sử dụng các con trỏ tiềm ẩn mà không yêu cầu bạn viết một đống mã phụ. Mã bạn viết rõ ràng hơn và dễ hiểu hơn - không phải là mối quan tâm nếu bạn đang làm việc trong một cửa hàng một người nơi bạn viết và duy trì tất cả mã, nhưng ở đây tại Corporateville, chúng tôi thường phải viết mã người khác sẽ duy trì và ngược lại, và nó được coi là lịch sự để bàn giao mã sạch nhất, rõ ràng nhất mà chúng ta có thể có. Có nhiều lần (chẳng hạn như khi chuyển một biến con trỏ cho người gọi từ bên ngoài Oracle) khi con trỏ rõ ràng là cần thiết, nhưng đối với hầu hết mã tôi đang sử dụng con trỏ FOR-LOOP ẩn - LOVING it! (Và điểm thưởng bổ sung cho những người có thể nhớ lại nơi rằng đến từ :-)

Chia sẻ và thưởng thức.