2011-04-15 30 views
6

Tôi đang sử dụng System.Data.OracleClient mà không tham số ràng buộc theo tên và vị xác nhận rằng CommandText và thông số được đồng bộ:ORA-01.008 với tất cả các biến ràng buộc

public string CommandText { get; set; } 
    public IEnumerable<OracleParameter> Parameters { get; set; } 

    private void VerifyThatAllParametersAreBound() 
    { 
     var variableNames = Regex.Matches(CommandText, ":\\w+") 
      .Cast<Match>().Select(m => m.Value).ToArray(); 
     var parameteterNames = Parameters.Select(p => p.ParameterName).ToArray(); 

     var unboundVariables = variableNames.Except(parameteterNames).ToArray(); 
     if (unboundVariables.Length > 0) 
     { 
      throw new Exception("Variable in CommandText missing parameter: " 
       + string.Join(", ", unboundVariables) + "."); 
     } 

     var unboundParameters = parameteterNames.Except(variableNames).ToArray(); 
     if (unboundParameters.Length > 0) 
     { 
      throw new Exception("Parameter that is not used in CommandText: " 
       + string.Join(", ", unboundParameters) + "."); 
     } 
    } 

Tuy nhiên một truy vấn ném ORA-01008: not all variables bound. Khi chèn thủ công các tham số-giá trị vào CommandText vi phạm, truy vấn sẽ chạy, vì vậy các CommandText và Parameters-values ​​phải là ok. Tôi đang sử dụng: làm tiền tố cho cả các biến và tên tham số và nó hoạt động cho các truy vấn khác.

Làm cách nào để xác định nguyên nhân của ngoại lệ này?

+1

bạn có mã tạo truy vấn không? Ngoài ra, bạn đã thử với oracle (hoặc các nhà cung cấp khác) .net clients? Tôi nghĩ rằng Microsoft không còn cung cấp cho khách hàng oracle. –

+0

Tôi mơ hồ nhớ một vấn đề với một trong những khách hàng Oracle rằng các tham số phải được ràng buộc theo đúng thứ tự mà chúng xuất hiện trong truy vấn hoặc nó sẽ không hoạt động - đó có phải là vấn đề ở đây không? – Rup

+0

@Nick - Lệnh này là bản cập nhật với ~ 40 thông số để dễ đọc và lý do ip tôi đã bỏ chúng. Tôi đã thử với ODT.NET từ Oracle nhưng đã gặp sự cố khi triển khai nó. (Xem thêm bình luận bên dưới.) – Grastveit

Trả lời

7

Sai lầm không chỉ định DBNull.Value cho giá trị null. Vì vậy,

new OracleParameter(":Foo", item.Foo) 

phải preplaced với

item.Foo == null 
    ? new OracleParameter(":Foo", DBNull.Value) 
    : new OracleParameter(":Foo", item.Foo) 

Tôi nghĩ rằng nó đã làm việc trước đó với ODT.NET mà không null-séc, nhưng chưa xác nhận nó. Rõ ràng System.Data.OracleClient đang giảm tham số với giá trị null.

0

Tôi tin rằng Microsoft có deprecated OracleClient như một phần của ADO.NET khoảng 2 năm trước.

Bạn có thể xem xét sử dụng các thành phần truy cập dữ liệu của Oracle (ODAC odp.net). Dễ xây dựng (và kiểm tra đếm) các tham số sử dụng lớp OracleParameter. Thiết lập và cài đặt tài liệu được tìm thấy here. Oh, bạn có thể nhận được vào khuôn khổ Entity của họ (và LINQ) hỗ trợ cũng (vẫn còn beta tôi nghĩ?).

Điều gì đó cần xem xét nghiêm túc.

+0

Vâng, tôi thà sử dụng những gì cả hai oracle và microsoft khuyến cáo, nhưng đã phải đặt nỗ lực của tôi [giữ] [http://stackoverflow.com/questions/5581752/program-defensive-against-odac-instantclient). Với mã lỗi năm chữ số, tôi hơi thất vọng về các thông báo chung. ;) – Grastveit

3

Nếu bạn vượt qua rỗng như giá trị tham số, bạn nhận được "Không phải tất cả các biến ràng buộc" Nếu bạn vượt qua DBNull.Value bạn nhận được lỗi runtime đâu đó trong OracleClient. Để vượt qua NULL, sử dụng chuỗi.Empty, OracleClient chuyển đổi thành NULL cho bất kỳ loại cơ sở dữ liệu nào.

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