2012-01-04 21 views
10

Oracle 10.2.0.5Cách xác định các giá trị không hợp lệ (bị hỏng) được lưu trữ trong các cột Oracle DATE

Cách dễ nhất để xác định các hàng trong bảng có giá trị "không hợp lệ" trong cột DATE là gì. Bởi "không hợp lệ" ở đây những gì tôi có nghĩa là một đại diện nhị phân vi phạm các quy tắc của Oracle cho các giá trị ngày tháng.

Gần đây, tôi gặp sự cố với ngày không hợp lệ được lưu trữ trong cột.

tôi đã có thể sử dụng một ngữ truy vấn để tìm một hàng có vấn đề đặc biệt:

WHERE TO_CHAR(date_expr,'YYYYMMDDHH24MISS') = '00000000000000' 

Trong trường hợp tôi đã có, các byte thế kỷ đã không hợp lệ ...

select dump(h.bid_close_date) from mytable h where h.id = 54321 

Typ=12 Len=7: 220,111,11,2,1,1,1 

Byte thế kỷ nên là 100 + hai chữ số thế kỷ. Trong trường hợp này, có thêm 100 được thêm vào, như thể giá trị thế kỷ là "120", tạo ra năm "12011". (Cách duy nhất tôi biết để có được các giá trị DATE không hợp lệ vào cơ sở dữ liệu là sử dụng OCI, sử dụng biểu diễn DATE 7 byte gốc.)

Trong trường hợp này, hàm TO_CHAR trả về một chuỗi có thể nhận dạng mà tôi có thể sử dụng để xác định giá trị DATE đáng giá.

Câu hỏi của tôi: có cách tiếp cận tổng quát hơn hoặc dễ dàng hơn (tốt nhất là sử dụng câu lệnh SQL SELECT) để xác định các hàng có giá trị "không hợp lệ" trong cột DATE.

+0

Bạn có thể chọn tất cả các ngày không nằm trong phạm vi hợp lệ được chỉ định không? – ProfessionalAmateur

+1

Có * là * một lỗi trong các phiên bản trước của Oracle (9.x?) Cho phép chia cho 0 giá trị INTERVAL để không bị phát hiện và tạo ra các giá trị không hợp lệ. –

+0

Làm thế nào bạn quản lý để đưa chúng vào cơ sở dữ liệu ở nơi đầu tiên? –

Trả lời

3

Nếu không có thêm một chức năng, một vị đơn giản

TO_CHAR(date_col,'YYYYMMDDHH24MISS') = '000000000000' 

dường như là thỏa đáng để xác định giá trị hỏng được lưu trữ trong một cột NGÀY Oracle. Việc bổ sung một hàm có vẻ không cần thiết. Việc kiểm tra các ngày bị hỏng có thể được thực hiện trong câu lệnh SQL SELECT và không yêu cầu người dùng phải có đặc quyền CREATE FUNCTION trên cơ sở dữ liệu.

4

Đây là một trường hợp khá bất thường (mặc dù tôi đã bắt gặp một cái gì đó tương tự một lần trước đây). Vấn đề phổ biến hơn là tìm ngày không hợp lệ được giữ như là chuỗi trong một cột ngày tháng. Bạn có thể điều chỉnh giải pháp cho tình huống của mình bằng cách tạo trình xác thực ngày của riêng bạn.

Something như thế này:

create or replace function is_a_date 
    (p_date in date) 
    return varchar2 
is 
    d date; 
begin 
    d := to_date(to_char(p_date, 'SYYYYMMDDHH24MISS'), 'SYYYYMMDDHH24MISS') ; 
    if d != p_date then 
     return 'not a proper date'; 
    else 
     return 'good date'; 
    end if; 
exception 
    when others then 
     return 'not a date'; 
end; 
/

này chuyển đổi một ngày thành một chuỗi và ngược lại. Nó bắt ngoại lệ được ném theo ngày. Nếu sản phẩm cuối cùng không giống như ngày đầu vào thì có lẽ có gì đó đã mất trong bản dịch; thành thật mà nói, tôi không chắc liệu ngày 12011 có thành công với chuỗi không, vì vậy đây là phương pháp tiếp cận thắt lưng. Đó là một chút khó khăn bằng văn bản tiện ích này mà không có một số dữ liệu thử nghiệm!

Truy vấn này sẽ xác định tất cả các ngày không hợp lệ:

select h.id, dump(h.bid_close_date) 
from mytable h 
where h.bid_close_date is not null 
and is_a_date(h.bid_close_date) != 'good date'; 
+0

+1 Giả sử điều này thực sự hoạt động (tôi không có dữ liệu thử nghiệm) Tôi thích điều này tốt hơn nhiều so với ý tưởng phân tích chuỗi bởi 'dump'. –

+1

Để phù hợp với cách thức chung mà nhiều hàm hoạt động, một hàm có thể trả về null, nếu 'p_date' là null. Đối với việc sử dụng cụ thể này, việc nuốt null và báo cáo nó là một ngày tốt có ý nghĩa. –

+0

@ShannonSeverance - trong trường hợp này tôi nghĩ tùy chọn hợp lý nhất là lọc truy vấn, vì vậy chúng tôi chỉ bận tâm với các hàng có cột ngày tháng được điền. – APC

0

tôi muốn đi cho một phương pháp có thể được thực hiện như một hạn chế kiểm tra, có thể thông qua kiểm tra xem ngày nằm trong khoảng của pháp luật giá trị.

Tuy nhiên, hãy tự hỏi liệu liệu nó có hợp lệ để có ngày 1066-10-14 không? Đó là một giá trị pháp lý, nhưng bạn có thể không có hóa đơn được in vào ngày đó, ví dụ. Vì vậy, bạn có thể muốn cuộn kiểm tra ngày không hợp lệ thành một vấn đề lớn hơn về những gì bạn thực sự coi là hợp lệ trong ngữ cảnh của ứng dụng của bạn.

+0

Điều này không trả lời câu hỏi tôi đã hỏi, đó là về phương pháp tốt nhất để xác định tham nhũng hiện có trong một cột cơ sở dữ liệu Oracle DATE. – spencer7593

+0

Thật vậy không - đó là lời khuyên về cách chọn phương pháp luận và cân nhắc về hiệu lực dữ liệu rộng hơn. –

0

này xác định tháng không hợp lệ

SELECT rowid, 
     pk_column, 
     DUMP(date_column, 1010) AS dump1 
FROM table 
WHERE TO_NUMBER(SUBSTR(DUMP(date_column, 1010), INSTR(DUMP(date_column, 1010), 
               ',', 1, 2 
                ) + 1, 
            INSTR(DUMP(date_column, 1010), ',', 1, 3) - (
            INSTR(DUMP(date_column, 1010), ',', 1, 2) + 1 
           ))) = 0; 

Cập nhật sử dụng cùng một mệnh đề where, tôi thấy số tháng là zero trong những trường hợp này.

Các vấn đề liên quan