2012-11-07 39 views
60

thể trùng lặp:
Why does Oracle 9i treat an empty string as NULL?rỗng vs chuỗi rỗng trong Oracle

Tôi có một bảng trong Oracle 10g tên TEMP_TABLE với chỉ có hai cột - iddescription chỉ vì lợi ích của cuộc biểu tình .

Cột id là chuỗi khóa được tạo thứ tự của loại NUMBER(35, 0) not null và cột DESCRIPTION là một loại VARCHAR2(4000) not null.

Cấu trúc bảng cơ bản trong trường hợp này sẽ trông giống như sau.

+--------------+-----------+---------------+ 
|Name   | Null?  | Type   | 
+--------------+-----------+---------------+ 
|ID   | NOT NULL | NUMBER(35) | 
|DESCRIPTION | NOT NULL | VARCHAR2(4000)| 
+--------------+-----------+---------------+ 

Sau khi tạo bảng này, tôi đang cố gắng chèn các lệnh sau đây INSERT.

INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful 
INSERT INTO temp_table (id, description) VALUES (2, ''); ->unsuccessful 

Cả hai đều không thành công như rõ ràng bởi vì các hạn chế not null được thi hành trên cột DESCRIPTION.

Trong cả hai trường hợp, Oracle phàn nàn

ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION") 

Chuỗi trống được coi là một giá trị NULL trong Oracle.


Nếu tôi bỏ not null hạn chế trên cột DESCRIPTION thì cấu trúc bảng cơ bản sẽ trông giống như sau

+--------------+-----------+---------------+ 
|Name   | Null?  | Type   | 
+--------------+-----------+---------------+ 
|ID   | NOT NULL | NUMBER(35) | 
|DESCRIPTION |   | VARCHAR2(4000)| 
+--------------+-----------+---------------+ 

và cả hai INSERT lệnh theo quy định sẽ thành công. Họ sẽ tạo hai hàng một với giá trị null và một hàng khác có một chuỗi trống '' trong cột DESCRIPTION của TEMP_TABLE.

Bây giờ, nếu tôi hành SELECT lệnh sau,

SELECT * FROM temp_table WHERE description IS NULL; 

sau đó rồi nó lấy cả các hàng trong đó một có giá trị null và người kia có một chuỗi rỗng '' trong cột DESCRIPTION.

Tuyên bố SELECT sau tuy nhiên lấy không có hàng từ TEMP_TABLE

SELECT * FROM temp_table WHERE description=''; 

Nó thậm chí không lấy hàng trong đó có một chuỗi rỗng trong cột DESCRIPTION.


Có lẽ, dường như Oracle đối xử với một giá trị null và một chuỗi rỗng '' khác nhau ở đây mà tuy nhiên không xuất hiện là trường hợp với tuyên bố INSERT trong đó cả một giá trị null và một chuỗi rỗng '' là ngăn không cho chèn vào cột có giới hạn not null. Tại sao nó như vậy?

+1

Làm thế nào để bạn thấy rằng có một chuỗi rỗng trong một trong các trường mô tả và null trong trường khác? –

+0

@ Flansch- Có lẽ, tôi giả định với những câu lệnh 'INSERT', vì tôi không biết rằng các chuỗi rỗng' '' 'được chuyển thành giá trị' null', xin lỗi. – Tiny

+0

Bạn có thể muốn đọc [* this *] (http://stackoverflow.com/a/203536/1057429) – alfasin

Trả lời

70

Điều này là do Oracle thay đổi nội bộ chuỗi rỗng thành giá trị NULL. Oracle đơn giản sẽ không cho phép chèn một chuỗi rỗng.

Mặt khác, SQL Server sẽ cho phép bạn thực hiện những gì bạn đang cố gắng đạt được.

Có 2 cách giải quyết ở đây:

  1. Sử dụng một cột đó khẳng định xem trường 'description' là hợp lệ hay không
  2. Sử dụng một số giá trị giả cho 'description' lĩnh vực nơi bạn muốn nó để lưu trữ chuỗi rỗng. (Tức là thiết lập các lĩnh vực được giả định dữ liệu thực sự của bạn 'stackoverflowrocks' sẽ không bao giờ gặp phải như một giá trị mô tả)

Cả hai đều là, tất nhiên, cách giải quyết ngu ngốc :)

+2

Trường hợp này chỉ có chuỗi hoặc với các kiểu dữ liệu khác? – Logicalj

26

Trong oracle một varchar2 trống và null đối xử như vậy, và các quan sát của bạn cho thấy điều đó.

khi bạn viết:

select * from table where a = ''; 

của nó giống như viết

select * from table where a = null; 

và không a is null

đó sẽ không bao giờ đánh đồng là true, vì vậy không bao giờ quay trở lại liên tiếp. tương tự trên chèn, một NOT NULL có nghĩa là bạn không thể chèn một null hoặc một chuỗi rỗng (được coi là rỗng)

+0

Điều này đặc biệt quan tâm nếu bạn so sánh 7.3 (không có java) và> = 8.0 (với java). –

+1

Ngoài ra, mệnh đề 'where not (a = '')' cũng không bao giờ đúng, bởi vì 'a = ''' là 'a = null', đánh giá thành' UNKNOWN' và 'not (UNKNOWN)' là ' UNKNOWN', điều đó không đúng. Để biết chi tiết về UNKNOWN, hãy xem thêm câu trả lời cho http://stackoverflow.com/questions/2692046/how-oracle-10g-evaluates-null-in-boolean-expressions –

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