2011-09-12 22 views
6

xem xét phương pháp này rất đơn giản:Làm cách nào để xử lý các giá trị NULL và thông thường mà không sử dụng các câu lệnh chuẩn bị khác nhau?

public ResultSet getByOwnerId(final Connection connection, final Integer id) throws SQLException { 
    PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?"); 
    statement.setObject(1, id); 
    return statement.executeQuery(); 
} 

Phương pháp dụ là vụ để chọn tất cả mọi thứ từ một số bàn nơi trận giá trị của một cột, mà nên được đơn giản. Các chi tiết xấu xí là đi qua NULL cho id sẽ dẫn đến một ResultSet trống, bất kể có bao nhiêu hàng có trong DB vì SQL định nghĩa NULL là không euqaling anyting, thậm chí không NULL. Cách duy nhất để chọn những hàng tôi biết đang sử dụng một khác nhau mệnh đề where:

SELECT * FROM MyTable WHERE MyColumn IS NULL 

Đáng tiếc là cách duy nhất để thực hiện công việc phương pháp đúng trong mọi trường hợp có vẻ là để có hai pathes thực hiện hoàn toàn khác nhau, một đối với trường hợp đối số id là null và một đối với các giá trị thông thường.

Điều này rất xấu và khi bạn có nhiều cột có thể bị vô hiệu hóa có thể rất lộn xộn một cách nhanh chóng. Làm thế nào có thể xử lý NULL và các giá trị bình thường với cùng một đường dẫn mã/tuyên bố?

+0

tôi không sử dụng JDBC, nhưng trong C# Tôi thường thiết lập này lên để các '='/'là NULL' động đã chọn?. Tham số, nếu có, vẫn bị ràng buộc thông qua câu lệnh đã chuẩn bị. –

+0

Nếu bạn đang sử dụng SQL Server, bạn chỉ có thể thực hiện 'SET ANSI_NULLS OFF' và' field = NULL' sẽ hoạt động. – NullUserException

+1

Hãy xem xét Hibernate hoặc JPA. Nó sẽ giúp bạn tiết kiệm từ JDBC boilerplate. – BalusC

Trả lời

0

Bạn có thể sử dụng một truy vấn như thế này:

select * from MyTable where 
    case when ?1 is null then MyColumn is null else MyColumn = ?1 

Nhưng nó reuses tham số tương tự, vì vậy tôi không biết liệu cú pháp tôi đã đề nghị sẽ làm việc (1?).

2

tôi đã không cố gắng này, nhưng cách để gửi null để PreparedStatements là sử dụng setNull() tùy chọn

PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?"); 
    if (id == null) 
     statement.setNull(1, java.sql.Types.INTEGER); 
    else  
     statement.setObject(1, id); 
    return statement.executeQuery(); 

EDIT: Cảm ơn câu trả lời @Gabe và @Vache. Nó không giống như có một cách dễ dàng để làm điều này khác hơn là tham gia một cách tiếp cận dài hơn để tự động tạo ra các chuẩn bị sẵn sàng.

Something như thế này nên làm việc -

String sql = " SELECT * FROM MyTable WHERE " + (id==null)?"MyColumn is null":"MyColumn = ?" ; 
     PreparedStatement statement = connection.prepareStatement(sql); 
     if (id != null) 
      statement.setObject(1, id); 
     return statement.executeQuery(); 
+0

Trong ANSI SQL, 'MyColumn = NULL' sẽ không bao giờ đúng, ngay cả khi' MyColumn' có giá trị 'NULL'. – Gabe

+0

Nó sẽ đặt một "SQL null", nhưng 'MyColumn = NULL' sẽ vẫn không trả về kết quả nào. 'setNull' chủ yếu được sử dụng cho các truy vấn chèn. – Vache

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