2010-10-05 30 views
8

Tôi đã sử dụng một truy vấn tham số để chèn giá trị vào một bảng Oracle, như vậy:Tại sao tôi nhận được ORA-01722 (số không hợp lệ)?

var q = "insert into MyTable(Field1, Field2...) values(:Field1, :Field2...)"; 
var cmd = new OracleCommand(q, conn); // conn is a pre-existing connection 
cmd.Parameters.Add("Field1", field1Val); 
cmd.Parameters.Add("Field2", field2Val); 
// etc... 
cmd.ExecuteNonQuery(); 

này đã làm việc tốt, nhưng đột nhiên này đã ngừng làm việc, và tôi nhận được Oracle lỗi ORA-01.722 (số không hợp lệ). Tôi đã kiểm tra các tham số, và tất cả các con số là số không hợp lệ. Tôi thậm chí còn thay thế các giá trị giả cho bất kỳ null, và tôi vẫn nhận được lỗi. Tôi đã thử cùng một truy vấn trong sql trực tiếp (sử dụng OraDeveloper Studio), và nó hoạt động, ngay cả với các tham số giống nhau.

Làm cách nào để theo dõi sự cố này?

EDIT: theo yêu cầu trong các ý kiến, đây là tạo ra bảng báo cáo:

CREATE TABLE ALPHA.VISITFINDINGS (
    ID NUMBER(12), 
    VISITID NUMBER(12) NOT NULL, 
    DESCRIPTION VARCHAR2(100), 
    CUSTOMIMAGE CLOB, 
    VISUALFINDINGSSECTIONMAPID NUMBER(12), 
    FINDINGSID NUMBER(12), 
    CONSTRAINT FK_VISITFINDINGS_AREA FOREIGN KEY (VISUALFINDINGSSECTIONMAPID) 
    REFERENCES ALPHA.VISUALFINDINGSSECTIONMAP(VISUALFINDINGSSECTIONMAPID), 
    CONSTRAINT FK_VISITFINDINGS_FINDINGS FOREIGN KEY (FINDINGSID) 
    REFERENCES ALPHA.FINDINGS(FINDINGSID), 
    CONSTRAINT FK_VISITFINDINGS_VISIT FOREIGN KEY (VISITID) 
    REFERENCES ALPHA.VISITS(VISITID), 
    CONSTRAINT PK_VISITFINDINGS PRIMARY KEY (ID)) 
TABLESPACE USERS 
STORAGE (
    INITIAL 64K 
    MAXEXTENTS UNLIMITED 
) 
LOGGING; 
+2

Xin vui lòng gửi câu lệnh CREATE TABLE cho bảng. Tôi đoán là các giá trị bạn đang chèn lớn hơn giá trị được phân bổ cho loại dữ liệu. IE: Cột là NUMBER (3) và bạn đang cố chèn 1.000. –

+0

tạo bảng sao kê được đăng. –

Trả lời

28

Tôi đã trả lời tín dụng rồi, nhưng tôi nghĩ đáng nói ở đây chính xác gốc rễ của vấn đề của tôi là gì, trong trường hợp ai đó tìm thấy mục này trong khi tìm kiếm câu trả lời cho vấn đề của chính họ.

Vấn đề là C# thực hiện truy vấn tham số cho Oracle có chứa một lỗi nghiêm trọng và nguy hiểm tiềm tàng - một "hố trong phạm vi công cộng" thực:

Nó không quan trọng những gì bạn đặt tên cho thông số của bạn; chúng phải được thêm vào theo thứ tự xuất hiện trong truy vấn.

Xem thêm here.

+2

Vì đây là chính xác hơn, bạn có lẽ nên loại bỏ kiểm tra từ câu trả lời của tôi và đánh dấu này thay vào đó! – Rup

+0

@Rup - Bạn chính đáng, bạn. ;) –

+3

Được xác nhận trong chủ đề khác, đây không phải là lỗi, mà là một tính năng. Tất nhiên, nó sẽ là một tính năng rất nguy hiểm và vô dụng như là một tính năng và một lỗi sau đó. Tuy nhiên, họ nói nếu bạn đặt OracleCommand.BindByName = true, nó sẽ hoạt động như mong muốn. –

5

Khi bạn nói rằng bạn đã kiểm tra các thông số bạn có nghĩa là Parameters bộ sưu tập trên lớp SqlCommand? Bạn có thể bị lỗi trong số this note on the SqlParameter page:

Thận trọng khi bạn sử dụng quá tải này của hàm tạo SqlParameter để chỉ định giá trị tham số nguyên. Bởi vì quá tải này có giá trị của kiểu Object, bạn phải chuyển đổi giá trị tích phân thành kiểu đối tượng khi giá trị bằng 0, như ví dụ C# sau đây minh họa. Sao chép

Parameter = new SqlParameter("@pname", Convert.ToInt32(0)); 

Nếu bạn không thực hiện chuyển đổi này, trình biên dịch giả định rằng bạn đang cố gắng để gọi SqlParameter (string, SqlDbType) constructor quá tải.

tôi muốn đề nghị bạn sử dụng một cái gì đó giống như

cmd.Parameters.Add(
    new SqlParameter("Field1", SqlDbType.Int32) { Value = field1Val }); 

thay vì để thiết lập một cách rõ ràng các loại.

+3

OP đang sử dụng Oracle, không phải SQL Server, vì vậy đó sẽ là OracleParameter ... nhưng câu trả lời của bạn vẫn là viết tắt. Tuy nhiên nó không giải thích tại sao nó được sử dụng để làm việc ... –

+0

D'oh, xin lỗi. Tôi không thể nhớ những gì phiên bản Oracle được gọi là vì vậy tôi muốn sử dụng tên lớp cơ sở, DbParameter.Đúng, tôi không chắc chắn tại sao điều đó có thể đã thay đổi mọi thứ trừ khi anh ta chỉ mới bắt đầu truyền tham số bằng 0. – Rup

+0

+1 Đó là một dự đoán tốt, nhưng không - tôi lặp lại thông qua các tham số thực tế trong chế độ gỡ lỗi và kiểm tra tất cả các giá trị của chúng và tất cả đều chính xác. (Thật thú vị khi lưu ý rằng tất cả các giá trị được chuyển thành chuỗi - có vẻ vô lý khi chuyển đổi một số thành chuỗi trên máy khách, chỉ để bạn có thể chuyển đổi nó trở lại ở phía máy chủ!) –

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