2016-05-19 17 views
5

Một trong những công việc của OJDBC là ánh xạ các kiểu dữ liệu Oracle với các kiểu Java.Tại sao OJDBC 7 ánh xạ loại dữ liệu CHAR thành một chuỗi Java?

Tuy nhiên, chúng tôi nhận thấy rằng nếu chúng tôi cung cấp loại dữ liệu CHAR, thì nó không được ánh xạ tới java.lang.String. Các phiên bản hiển thị hành vi này là: OJDBC7 v12.1.0.2OJDBC6 v12.1.0.1. Các phiên bản cũ đã thực sự ánh xạ loại dữ liệu CHAR đến: java.lang.String.

Khi đào sâu hơn, chúng tôi phát hiện ra rằng có một lớp: StructMetaData trong gói OJDBC oracle.jdbc.driver triển khai thực hiện kiểu dữ liệu Oracle đối với ánh xạ kiểu Java. Có một phương thức bên trong nó: 'getColumnClassName (int arg0)' đáng chú ý. Chúng tôi nhận thấy rằng cho OJDBC v7, các trường hợp ánh xạ tới java.lang.String như sau:

int arg1 = this.getColumnType(arg0); 
    switch (arg1) { 
    case -104: 
     return "oracle.sql.INTERVALDS"; 
    case -103: 
     return "oracle.sql.INTERVALYM"; 
    case -102: 
     return "oracle.sql.TIMESTAMPLTZ"; 
    case -101: 
     return "oracle.sql.TIMESTAMPTZ"; 
    case -15: 
    case -9: 
    case 12: 
     return "java.lang.String"; 
    ... 

Tuy nhiên, trong triển khai OJDBC già đi, nó trông như thế này:

int arg1 = this.getColumnType(arg0); 
    switch (arg1) { 
    case -104: 
     return "oracle.sql.INTERVALDS"; 
    case -103: 
     return "oracle.sql.INTERVALYM"; 
    case -102: 
     return "oracle.sql.TIMESTAMPLTZ"; 
    case -101: 
     return "oracle.sql.TIMESTAMPTZ"; 
    case -15: 
    case -9: 
    case 1: 
    case 12: 
     return "java.lang.String"; 
    ... 

Có một trường hợp thêm ánh xạ tới java.lang.String trong trường hợp sau viz. 'trường hợp 1'. 'Trường hợp 1' này không được ánh xạ tới java.lang.String trong đoạn mã đầu tiên được hiển thị ở trên.

On nhìn sâu hơn, 'trường hợp 1' này được ánh xạ tới CHAR trong phương pháp getColumnTypeName(int arg0) của lớp cùng StructMetaData:

public String getColumnTypeName(int arg0) throws SQLException { 
    int arg1 = this.getColumnType(arg0); 
    int arg2 = this.getValidColumnIndex(arg0); 
    switch (arg1) { 
    case -104: 
     return "INTERVALDS"; 
    case -103: 
     return "INTERVALYM"; 
    case -102: 
     return "TIMESTAMP WITH LOCAL TIME ZONE"; 
    case -101: 
     return "TIMESTAMP WITH TIME ZONE"; 
    case -15: 
     return "NCHAR"; 
    case -13: 
     return "BFILE"; 
    case -9: 
     return "NVARCHAR"; 
    case -2: 
     return "RAW"; 
    case 1: 
     return "CHAR"; 
... 

Bởi vì điều này, nếu chúng ta sử dụng OJDBC 7 hoặc OJDBC6 v12.1.0.1 và chỉ định CHAR như kiểu dữ liệu cho một cột, các mã sau trả null trên gọi cho chỉ mục của cột này:

for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) { 
    ... 
    resultSetMetaData.getColumnClassName(columnIndex) 
    ... 

Nếu tôi thay thế một phiên bản cũ của jar OJDBC (ví dụ: 11.2.0.3), sau đó cùng một mã trả về: java.lang.String. Đây có phải là lỗi hoặc bị xóa bởi thiết kế không? Có ai phải đối mặt với cùng một vấn đề trước đây không?

+1

Bạn đã kiểm tra ghi chú phát hành của tài xế chưa? Nếu bạn nghĩ rằng điều này là sai, mở một SR với hỗ trợ Oracle của tôi. Tôi hài lòng nhất với các giải pháp được cung cấp. –

Trả lời

0

Bắt tốt ...!

Nó thực sự trông giống như một lỗi; có lẽ lập luận duy nhất chống lại là nó sẽ là một cái nhìn vô cùng lớn của Oracle.

Pro lỗi:

  • ngược vấn đề tương thích.Cập nhật của trình điều khiển JDBC sẽ phá vỡ các ứng dụng hiện được dựa một cách rõ ràng trên CHAR khai
  • note này về JPublisher Data Type and Java-to-Java Type Mappings mô tả các bản đồ như của 12c

(lưu ý hàng đầu tiên, liên quan đến các loại CHAR, mà bản đồ để java.lang.String)

| SQL and PL/SQL Data Type | Oracle Mapping | JDBC Mapping 
|------------------------- |------------------|----------------------------------------------- 
| CHAR, CHARACTER, LONG, |     | 
|STRING, VARCHAR, VARCHAR2 | oracle.sql.CHAR | java.lang.String 
| NCHAR, NVARCHAR2   | oracle.sql.NCHAR | oracle.sql.NString 
| NCLOB     | oracle.sql.NCLOB | oracle.sql.NCLOB 

Against lỗi:

  • Giả thuyết ưa thích có thể cho rằng Oracle đang cố gắng loại bỏ CHAR s khỏi các loại được hỗ trợ. Thật vậy, loại CHAR thực sự không có lợi ích nào trên VARCHAR2 và một số nhược điểm khiến nó trở thành một lựa chọn không có. Trong quá khứ tôi thích thực tế rằng một "CHAR" giao tiếp với các nhà phát triển khác ý định của bạn để xác định một mục với một chiều dài được xác định trước và không thay đổi, nhưng nó thậm chí không thực thi điều này (nó chỉ đệm chuỗi, nếu bạn điền nó với quá một giá trị ngắn). Nếu bạn quan tâm, có một phần trong cuốn sách tuyệt vời Expert Oracle Database Architecture - Oracle Database 9i, 10g, and | Thomas Kyte | Apress dành riêng cho chủ đề. Bạn có thể đọc một đoạn trích trong Ask Tom "Char Vs Varchar", tại điểm mà tác giả trích dẫn cuốn sách của mình:

Thực tế là một CHAR/NCHAR thực sự là không có gì hơn một VARCHAR2/NVARCHAR2 trong ngụy trang làm cho tôi có ý kiến rằng thực sự chỉ có hai loại chuỗi ký tự để xem xét, cụ thể là VARCHAR2 và NVARCHAR2. Tôi chưa bao giờ tìm thấy cách sử dụng cho loại CHAR trong bất kỳ ứng dụng nào. Vì một loại CHAR luôn luôn bỏ trống chuỗi kết quả ra một chiều rộng cố định, chúng tôi phát hiện nhanh chóng rằng nó tiêu thụ dung lượng tối đa cả trong phân đoạn bảng và bất kỳ phân đoạn chỉ mục nào. Điều đó sẽ đủ tệ, nhưng có một lý do quan trọng khác để tránh các kiểu CHAR/NCHAR: chúng tạo ra sự nhầm lẫn trong các ứng dụng cần lấy thông tin này (nhiều người không thể "tìm" dữ liệu của chúng sau khi lưu trữ nó). Lý do cho điều này liên quan đến các quy tắc so sánh chuỗi ký tự và độ nghiêm ngặt mà chúng được thực hiện. ....

[sau đó là một ví dụ tuyệt vời sau trong cùng một bài đăng; nó rất đáng đọc]

Thực tế là CHAR không tốt, tất nhiên không biện minh cho Oracle khỏi việc vi phạm các ứng dụng hiện có mà không có thông báo rõ ràng; vì vậy giả thuyết rằng đó là một lỗi rõ ràng là hợp lý hơn. Cho rằng về lý thuyết nó sẽ không có nhược điểm, như một workaround cực bạn có thể thay đổi tất cả các bảng liên quan để xác định lại các loại CHAR của họ như VARCHAR2 (nếu bạn có quyền làm như vậy, và nó là khả thi).

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