2012-03-27 29 views
7

Tôi thấy hành vi kỳ quặc này và tôi đang phá vỡ bộ não của mình với điều này ... bất cứ ai có bất kỳ ý tưởng nào?Chọn chuỗi như số trên Oracle

Oracle 10g: Tôi có hai bảng khác nhau, cả hai đã cột này có tên là "TESTCOL" như VARCHAR2 (10), không nullable.

Nếu tôi thực hiện truy vấn này trên table1, tôi nhận được kết quả đúng:

select * from table1 where TESTCOL = 1234; 

Note rằng Tôi đặc biệt không đặt '1234' ... nó không phải là một lỗi đánh máy, đó là một truy vấn được tạo động và tôi sẽ cố gắng không thay đổi nó (ít nhất là trong tương lai gần).

Nhưng, nếu tôi chạy cùng một truy vấn, trên table2, tôi nhận được thông báo lỗi này:

ORA-01722: Invalid number 

Cả hai truy vấn được chạy trên cùng một phiên, cùng cơ sở dữ liệu.

Tôi đã tham gia hai bảng này theo cột đó và tham gia hoạt động ok, vấn đề duy nhất hiển thị bất cứ khi nào tôi cố gắng sử dụng điều kiện đó.

Bất kỳ ý tưởng nào về những gì có thể khác với bảng này với bảng khác?

Xin cảm ơn trước.

Trả lời

22

Nếu TESTCOL chứa số không, thì Oracle có thể gặp sự cố khi chuyển đổi mục nhập TESTCOL thành số. Bởi vì, những gì nó làm nội bộ, đây là:

select * from table1 where TO_NUMBER(TESTCOL) = 1234; 

Nếu bạn như vậy chắc chắn rằng 1234 không thể được diễn tả như một VARCHAR đen, sau đó thử này thay vào đó, để so sánh giá trị varchar, chứ không phải là những số:

select * from table1 where TESTCOL = TO_CHAR(1234); 
3

Bạn đang gặp nguy hiểm của việc nhập nội dung ngầm ở đây.

Với biểu thức testcol = 1234 bạn tuyên bố rằng bạn muốn coi testcol là cột số, vì vậy, Oracle cố chuyển đổi tất cả các giá trị trong cột đó thành một số.

ORA-01722 xảy ra vì dường như ít nhất một giá trị trong cột đó là không phải một số.

Mặc dù bạn cho rằng đây là "không phải là lỗi đánh máy" thực sự là một. Đó là một lỗi cú pháp.

Bạn sẽ phải khai báo tham số của bạn như là một chuỗi chữ sử dụng dấu nháy đơn: where testcol = '1234'

Tạo một điều kiện đúng là giải pháp duy nhất cho vấn đề của bạn.

4

TABLE2.TESTCOL rõ ràng chứa các giá trị mà không phải là số.So sánh một chuỗi với một chữ số tạo ra một chuyển đổi ngầm định. Vì vậy, bất kỳ giá trị nào trong TESTCOL hich không thể chuyển sang một số sẽ làm hỏng ORA-1722.

Nó không đánh bạn khi bạn so sánh hai bảng vì bạn đang so sánh chuỗi.

Vì vậy, bạn có một số tùy chọn, neiher mà bạn sẽ thích. Câu trả lời rõ ràng nhất là làm sạch dữ liệu để TABLE2 không chứa số không. Lý tưởng nhất là bạn nên kết hợp điều này với việc thay đổi cột thành kiểu dữ liệu số. Nếu không, bạn có thể thay đổi trình tạo để nó tạo mã mà bạn có thể chạy với mô hình dữ liệu shonky. Trong trường hợp này có nghĩa là gói các chữ trong dấu ngoặc kép nếu cột được ánh xạ có kiểu dữ liệu ký tự.

-1

Sau đây sẽ hoạt động. Chỉ cần thay thế "vị trí của bạn".

select * 
from table1 
where (select TO_NUMBER(TESTCOL) 
     from table2 
     where "your where") = 1234; 
Các vấn đề liên quan