Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Không phải là tháng hợp lệ khi thực hiện thủ tục tham số IN với giá trị ngày tháng

Thủ tục của bạn nhận các tham số của loại timestamp . Bạn thực sự đang chuyển các tham số kiểu varchar2 trong cuộc gọi của bạn. Điều đó buộc Oracle phải thực hiện chuyển đổi ngầm định của varchar2 tham số cho timestamp sử dụng NLS_TIMESTAMP_FORMAT trong phiên của bạn . Điều đó có thể sẽ khác nhau đối với các phiên khác nhau, vì vậy có khả năng ít nhất một số phiên sẽ gặp lỗi do chuỗi không khớp với định dạng của NLS_TIMESTAMP_FORMAT của phiên đó . Bạn sẽ được phục vụ tốt hơn nhiều khi đi qua một dấu thời gian thực tế bằng cách gọi to_timestamp một cách rõ ràng hoặc bằng cách chuyển một ký tự dấu thời gian.

Sau đó, quy trình của bạn lấy timestamp và chuyển chúng vào to_date hàm số. to_date hàm không nhận tham số kiểu timestamp , nó chỉ nhận các tham số kiểu varchar2 . Điều đó buộc Oracle thực hiện một chuyển đổi ngầm khác đối với timestamp tham số cho varchar2 , sử dụng lại NLS_TIMESTAMP_FORMAT của phiên . Nếu NLS_TIMESTAMP_FORMAT của phiên không khớp với mặt nạ định dạng rõ ràng trong to_date của bạn gọi, bạn sẽ gặp lỗi hoặc chuyển đổi sẽ trả về kết quả mà bạn không mong đợi.

Nếu cột trong bảng của bạn thực sự thuộc loại date , bạn có thể so sánh trực tiếp date đến timestamp . Vì vậy, dường như không có bất kỳ lý do gì để gọi to_date nơi đây. Tuy nhiên, dựa trên dữ liệu mẫu của bạn, có vẻ như cột trong bảng của bạn thực sự thuộc loại timestamp thay vì date như mã của bạn ngụ ý, kể từ một date không có độ chính xác phân số giây. Nếu đúng như vậy, việc gọi to_date càng ít ý nghĩa hơn trong SELECT của bạn vì các tham số của bạn thực sự thuộc loại timestamp và cột của bạn thuộc loại timestamp . Chỉ cần so sánh timestamp giá trị.

Do đó, tôi đoán là bạn muốn thứ gì đó giống như

CREATE OR REPLACE PROCEDURE PROC1(
   V_STARTTIME    IN TIMESTAMP ,
   V_ENDTIME      IN TIMESTAMP )
BEGIN
  INSERT INTO TAB1( <<column name>> )
    SELECT COINS 
      FROM TAB2
     WHERE <<timestamp column name>> BETWEEN v_starttime AND v_endtime;
END;

và bạn muốn làm thủ tục bằng cách chuyển các dấu thời gian thực tế. Sử dụng ký tự dấu thời gian

Execute proc1(timestamp '2014-05-05 11:25:00', timestamp '2014-05-05 12:25:00' )

hoặc bằng cách gọi to_timestamp một cách rõ ràng

execute proc1( to_timestamp( '5/05/2014 11:25:00 AM', 'MM/DD/YYYY HH:MI:SS AM' ),
               to_timestamp( '5/05/2014 12:25:00 PM', 'MM/DD/YYYY HH:MI:SS AM' ) );

Điều đó sẽ loại bỏ tất cả các chuyển đổi kiểu ngầm hiện đang diễn ra.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle Trigger để cập nhật cùng một bảng

  2. Giới thiệu về tập hợp PL / SQL trong cơ sở dữ liệu Oracle

  3. Sử dụng trình tự Oracle để chèn id nhật ký vào 2 bảng từ jdbc?

  4. thay đổi trạng thái tài khoản người dùng Oracle từ EXPIRE (GRACE) thành OPEN

  5. Oracle 10:Sử dụng HEXTORAW để điền dữ liệu blob