Một trong các số 'kỷ nguyên' bằng số của bạn dường như quá lớn (hoặc quá nhỏ) đối với numtodsinterval()
chức năng để xử lý. Giá trị lớn nhất bạn có thể chuyển theo số giây là 2 ^ 31-1:
SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:7.0
SQL> select numtodsinterval(power(2,31), 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
01873. 00000 - "the leading precision of the interval is too small"
*Cause: The leading precision of the interval is too small to store the
specified interval.
*Action: Increase the leading precision of the interval or specify an
interval with a smaller leading precision.
Là một kỷ nguyên mà số thứ hai được phép cao nhất đại diện cho 2038-01-19 03:14:07. Đây là vấn đề của năm 2038 , về cơ bản.
Bạn cũng có thể đến đó với một số âm:
SQL> select numtodsinterval(-2208988800, 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
Sử dụng -power(2, 31)
kết thúc thành một giá trị dương, nhưng bất kỳ giá trị nào thấp hơn lỗi đó:
SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:7.0
SQL> select numtodsinterval(-power(2,31), 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:8.0
SQL> select numtodsinterval(-power(2,31) - 1, 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
Bạn đang chia cho 1000, vì vậy một trong các cột từ F đến K của bạn có giá trị vượt quá 2147483647000. Điều đó sẽ khá dễ tìm và bạn có thể muốn xem xét thêm ràng buộc kiểm tra vào các cột đó để chúng không thể được đặt cao - kiểm tra xem giá trị cột nhỏ hơn hoặc bằng 1000 * (power(2, 31) - 1)
. Và lớn hơn 0 hoặc lớn hơn- 1000 * (power(2, 31)
quá.
Lý do nó không bị lỗi khi bạn có bộ lọc như where Col1 = 123
là bộ lọc (vị từ) của bạn được đẩy lên truy vấn chế độ xem và (các) hàng có giá trị quá cao sẽ không được đánh giá. Có lẽ bạn chỉ có một giá trị như vậy và col1
của nó giá trị không 123 và col2
của nó giá trị không 'XYZ'. Nếu bạn xác định một hàng có vấn đề và lọc bằng cách sử dụng col1
thực của nó giá trị nó vẫn sẽ lỗi. Không có bộ lọc, đánh giá được thực hiện cho tất cả các hàng.
Số âm cụ thể mà bạn có dường như là một con số kỳ diệu:
SQL> select date '1970-01-01' - 2208988800/86400 from dual;
DATE'1970-01-01'-2208988800/86400
---------------------------------
1900-01-01 00:00:00
Nếu bạn muốn loại trừ điều đó thì bạn sẽ phải sửa đổi định nghĩa chế độ xem để thêm bộ lọc, ví dụ:
...
AND tab2.colh > 0
hoặc thay đổi biểu thức cột để xử lý nó, bỏ qua nó và để nó rỗng, hoặc có thể hữu ích hơn là trả về ngày kỳ diệu đó:
TO_CHAR(CASE WHEN tab2.colh = -2208988800000 THEN DATE'1900-01-01'
ELSE DATE'1970-01-01' + NUMTODSINTERVAL( tab2.colh / 1000,'SECOND')
END, 'YYYY/MM/DD HH24:MI:SS') AS Col13,
Bạn cũng có thể thay đổi từ sử dụng khoảng thời gian sang sử dụng số học ngày:
TO_CHAR(DATE'1970-01-01' + ( tab2.colh / 86400000 ), 'YYYY/MM/DD HH24:MI:SS') AS Col13,
Tuy nhiên, bạn sẽ phải sửa đổi định nghĩa chế độ xem thay vì truy vấn của mình, trừ khi colh
được đưa vào danh sách lựa chọn (có vẻ như không có) và ngay cả khi đó là bạn chỉ có thể loại trừ nó - và điều đó vẫn có thể không phải lúc nào cũng tránh được lỗi, tùy thuộc vào cách trình tối ưu hóa xử lý truy vấn.