2012-02-22 57 views
7

Tôi có các điều sau trong mệnh đề SQL where. Điều này đang chạy với một cơ sở dữ liệu Oracle. Trường sc_dt được định nghĩa trong db làm trường ngày.TO_DATE issue

sc_dt = TO_DATE('2011-11-03 00:00:00.0', 'YYYY-MM-DD') 

sản xuất các lỗi sau "date format picture ends before converting entire input string"

Khi tôi cố gắng để giải thích cho những giây phân đoạn (.0 trong trường hợp này) với những điều sau đây, tôi nhận được các lỗi sau.

sc_dt = TO_DATE('2011-11-03 00:00:00.0', 'YYYY-MM-DD HH24:MI:SS.FF') 

sản xuất các lỗi sau "date format not recognized"

Tôi thực sự chỉ là giả định rằng tôi cần .FF vào tài khoản cho .0 trong "từ" chuỗi. Tôi cũng đã thử .FF1, .FF2, ..., .FF9 với cùng một kết quả (tôi đang nắm lấy ống hút tại thời điểm này).

Theo như tôi thấy, trường sc_dt luôn có phần tháng/ngày/năm được điền (và không phải là phần giờ/phút/giây).

Tôi đang gỡ lỗi chương trình java đang thực hiện câu lệnh SQL ở trên làm tuyên bố đã chuẩn bị với giá trị 2011-11-03 00:00:00.0.

Làm cách nào để giải quyết vấn đề này?

Trả lời

6

Bạn cần sử dụng tùy chọn giây qua nửa đêm. Một cái gì đó như:

select TO_DATE('2011-11-03 00:00:01.1', 'YYYY-MM-DD HH24:MI:SS.SSSSS') from dual 

Hoặc này:

select TO_TIMESTAMP('2011-11-03 00:00:00.1', 'YYYY-MM-DD HH24:MI:SS.FF') from dual 
+1

Bạn, tử tế, rock. Tôi nên hỏi câu hỏi này HOURS trước! (chấp nhận điều này như là câu trả lời ngay sau khi tràn ngăn xếp sẽ cho tôi). Cảm ơn nhiều! – acedanger

+0

Chắc chắn, niềm vui của tôi! – northpole

+0

'.FF' không hoạt động đối với tôi. '.SSSSS' đã làm thủ thuật. – acedanger

0

src_dt = select TO_DATE('2011-11-03 00:00:01.1', 'YYYY-MM-DD HH24:MI:SS.SSSSS') from dual

Tôi đoán một ở trên nên làm việc nếu bạn chỉ cần một sản lượng ngày.

+2

gọi TO_DATE này sẽ chỉ hoạt động nếu phần của chuỗi nhận dạng giây phân đoạn xảy ra cũng là số giây kể từ nửa đêm (mà chỉ có thể xảy ra 9 lần một giờ). Nếu thời gian của bạn luôn là lúc nửa đêm, điều đó có thể không phải là một vấn đề. Nhưng nói chung, bạn sẽ nhận được ORA-01838: giây xung đột phút với số giây trong lỗi ngày. –

5

Một Oracle DATE cột như sc_dt sẽ luôn luôn có một ngày và một phần thời gian xuống đến từng giây. Tùy thuộc vào công cụ truy vấn của bạn và cách nó được cấu hình (thường là phiên của NLS_DATE_FORMAT), có thể thành phần thời gian không được hiển thị theo mặc định. Bạn có thể, tuy nhiên, nhìn thấy các thành phần thời gian bằng cách thực hiện một rõ ràng TO_CHAR

SELECT to_char(sc_dt, 'YYYY-MM-DD HH24:MI:SS') 
    FROM table_name 

Bởi vì một DATE chỉ lưu trữ thời gian để thứ hai, tuy nhiên, bạn không thể sử dụng giây phân đoạn trong mặt nạ dạng của bạn. Vì vậy, bạn sẽ cần phải làm một cái gì đó như thế này để trích xuất chỉ là phần của chuỗi lên đến giây phân số. Nếu bạn không được đảm bảo rằng chuỗi sẽ luôn luôn là 19 ký tự trước dấu thập phân, bạn có thể sử dụng INSTR cũng như tìm dấu thập phân và thực hiện mọi thứ trước đó.

TO_DATE(substr('2011-11-03 00:00:00.0', 1, 19), 'YYYY-MM-DD HH24:MI:SS') 

Vì điều này đến từ một ứng dụng Java, tuy nhiên, bạn nên sử dụng đúng loại dữ liệu. Nếu bạn liên kết một ngày Java (java.sql.Date) bằng cách sử dụng phương thức setDate trên câu lệnh đã chuẩn bị chứ không phải ràng buộc một chuỗi, thì bạn sẽ không phải đối phó với định dạng chuỗi trong câu lệnh SQL của mình.

+2

Tôi thích giải pháp của Justin với 'SUBSTR' tốt hơn so với những người khác sử dụng mô hình định dạng' .SSSSS', cả hai lý do ông đưa ra nhận xét của mình về các câu trả lời khác, và vì rõ ràng hơn là thành phần thứ hai của phân đoạn đang bị hủy bỏ. –

+0

@Justin - Cảm ơn bạn đã giải thích! Nó giúp tôi hiểu tại sao tôi làm những gì tôi đang làm. – acedanger

+0

@Justin: Một lý do không sử dụng setDate là chuyển đổi múi giờ tiềm ẩn xảy ra giữa Java và cơ sở dữ liệu. –

3

Tôi nhận thấy chuỗi này cũ hơn một năm nhưng ... Một tùy chọn khác chỉ để ném nó vào có thể là:

src_dt=select TO_DATE('2011-11-03 00:00:01.1234', 'YYYY-MM-DD HH24:MI:SS.?????') from dual; 

Lưu ý: có thêm '?' ném vào để minh họa rằng bạn thậm chí có thể gắn bó thêm một vài '?'. Không có khiếu nại từ Oracle nếu các chữ số đại diện bởi '?' KHÔNG có bất kỳ ký tự tương ứng nào trong chuỗi thời gian nguồn. Điều này có thể hữu ích nếu bạn không chắc chắn về độ chính xác của giây bạn nhận được.

Tùy chọn này cung cấp một số tính linh hoạt cho định dạng "giây phân số" từ thời gian nguồn của bạn. Tôi không biết rằng điều này thực sự là tài liệu ở bất cứ đâu.

+1

Của tất cả các giải pháp này chỉ hoạt động cho tôi. –

1

Tôi đã làm điều này:

ALTER SESSION 
SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS.?'; 


--Change the decimal 
ALTER SESSION 
SET NLS_NUMERIC_CHARACTERS = ',.'; 

Và nó làm việc cho tôi