Nếu tôi cài đặt ARRAYSIZE 1 trong SQL * Plus, các bản ghi vẫn được tìm nạp theo cặp. Tại sao?


7

Tôi đã nghĩ về việc viết một tiện ích giống như đơn giản tail -f để "theo dõi" tiến trình của một số số liệu trong cơ sở dữ liệu:

create or replace function tail_f return varchar2_tab pipelined as
   n number;
begin

    loop
      exit when ...

      select count(*) into n from ... where ...;

      pipe row(sysdate || ' n= ' || n);
      dbms_lock.sleep(60);
    end loop;

    return;
end tail_f;

Và sau đó tôi muốn select * from table(tail_f)vào SQL * Plus.

Để tìm nạp từng hàng một, tôi SET ARRAYSIZE 1. Tuy nhiên, các bản ghi (ngoại trừ bản đầu tiên) được tìm nạp theo cặp.

Có một lời giải thích cho điều này và làm thế nào tôi có thể nhận được các hồ sơ ngay khi một trong những đường ống?

Câu trả lời:


9

Lỗi Metalink 9103343 tuyên bố:

Đây là hành vi dự kiến. SQL * Plus được viết bằng oci và oci có giá trị tìm nạp mặc định là 1 hàng. Tuy nhiên, việc tìm nạp trước khi tìm nạp (trái ngược với thực thi) chỉ diễn ra khi bạn không thực hiện tìm nạp mảng, do đó, khi mảng được kích hoạt là 1. Bất kể mảng tìm nạp đầu tiên trong dấu vết luôn là 1 hàng vì 1 hàng được tìm nạp trước việc thực hiện. Sau đó, nó thực hiện tìm nạp vô hướng, do đó, một hàng được yêu cầu cộng với một hàng được tìm nạp trước hoặc nó thực hiện tìm nạp mảng để bạn thấy, ví dụ: a) Arrayaysize = 1, tìm nạp là: 1, 2, 2, ... b) Arrayaysize = 2, các lần tìm nạp là: 1, 2, 2, ... c) Arrayaysize = 5, các lần tìm nạp là: 1, 5, 5, ...

Xem thêm Metalink doc 1265916.1


Đó là xác nhận sự nghi ngờ của tôi với ghi chú metalink.
René Nyffalanger

5

Đây dường như là một sự giải thích của SQL * Plus và arraysizehơn là các hàm pipelined - những điều sau đây cho thấy hiệu quả tương tự:

create or replace function pause return integer as
begin
  dbms_lock.sleep(2);
  return 1;
end;
/

select pause from dual connect by level<10;

Bạn có thể (sắp xếp) giải quyết vấn đề bằng cách chọn các hàng hai lần và loại bỏ mỗi giây:

select /*+ ordered first_rows(1) */ *
from table(tail_f) cross join (select level from dual connect by level<=2);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.