Làm cách nào tôi có thể bỏ một ràng buộc “not null” trong Oracle khi tôi không biết tên của ràng buộc?


85

Tôi có một cơ sở dữ liệu có ràng buộc NOT NULL trên một trường và tôi muốn loại bỏ ràng buộc này. Yếu tố phức tạp là ràng buộc này có tên do hệ thống xác định và tên của ràng buộc đó khác nhau giữa máy chủ sản xuất, máy chủ tích hợp và các cơ sở dữ liệu nhà phát triển khác nhau. Quy trình hiện tại của chúng tôi là kiểm tra các tập lệnh thay đổi và một tác vụ tự động thực thi các truy vấn thích hợp thông qua sqlplus đối với cơ sở dữ liệu đích, vì vậy tôi muốn một giải pháp có thể được gửi thẳng vào sqlplus.

Trên cơ sở dữ liệu của riêng tôi, SQL để loại bỏ điều này sẽ là:

alter table MYTABLE drop constraint SYS_C0044566

Tôi có thể thấy hạn chế khi truy vấn all_constraintschế độ xem:

select * from all_constraints where table_name = 'MYTABLE'

nhưng tôi không chắc chắn làm thế nào để làm việc với các SEARCH_CONDITION's LONGkiểu dữ liệu hoặc làm thế nào tốt nhất để tự động xóa các hạn chế nhìn lên ngay cả sau khi tôi biết tên của nó.

Vì vậy, làm thế nào tôi có thể tạo một kịch bản thay đổi có thể loại bỏ ràng buộc này dựa trên những gì nó là gì, thay vì tên của nó là gì?


CHỈNH SỬA: Câu trả lời của @ Allan là một câu trả lời hay, nhưng tôi lo ngại (do tôi không có kiến ​​thức chuyên môn về Oracle) rằng có thể không hoàn toàn đúng khi bất kỳ ràng buộc nào có thể có tên do hệ thống tạo ra sẽ liên quan đến nó để loại bỏ ràng buộc mà không cần phải biết tên của nó. Có đúng là sẽ luôn có cách để tránh phải biết tên của ràng buộc do hệ thống đặt tên khi loại bỏ ràng buộc đó một cách hợp lý không?


3
Chỉ để thỏa mãn sự tò mò của bạn: Ràng buộc NOT NULL là kiểu ràng buộc duy nhất trong Oracle mà bạn có thể loại bỏ mà không cần biết tên của ràng buộc. Tất cả các loại ràng buộc khác bạn cần biết tên của ràng buộc.
Jeffrey Kemp

Câu trả lời:


166
alter table MYTABLE modify (MYCOLUMN null);

Trong Oracle, các ràng buộc không null được tạo tự động khi không chỉ định null cho một cột. Tương tự như vậy, chúng tự động bị loại bỏ khi cột được thay đổi để cho phép null.

Làm rõ câu hỏi đã sửa đổi : Giải pháp này chỉ áp dụng cho các ràng buộc được tạo cho các cột "không rỗng". Nếu bạn chỉ định "Khóa chính" hoặc một ràng buộc kiểm tra trong định nghĩa cột mà không đặt tên cho nó, bạn sẽ kết thúc với một tên do hệ thống tạo cho ràng buộc (và chỉ mục, cho khóa chính). Trong những trường hợp đó, bạn cần biết tên để bỏ nó. Lời khuyên tốt nhất là tránh trường hợp này bằng cách đảm bảo rằng bạn chỉ định tên cho tất cả các ràng buộc khác với "not null". Nếu bạn thấy mình ở trong tình huống cần loại bỏ một trong những ràng buộc nói chung, có thể bạn sẽ cần sử dụng đến PL / SQL và các bảng định nghĩa dữ liệu.


Điều đó có vẻ thực sự quá tốt để trở thành sự thật, nhưng nó chắc chắn xử lý trường hợp hiện tại của tôi và rõ ràng là đơn giản! Có trường hợp nào trong oracle mà tên ràng buộc có thể được tạo ra từ hệ thống nhưng sql không thể được viết để tránh tên ràng buộc như vậy không?
Chris Farmer

1
Cảm ơn ... hóa ra các not nullràng buộc là những thứ duy nhất có tên hệ thống trong lược đồ của tôi có khả năng ảnh hưởng đến tôi theo cách này.
Chris Farmer

16

Thử:

alter table <your table> modify <column name> null;

1

Chỉ cần nhớ rằng, nếu trường bạn muốn tạo nullable là một phần của khóa chính, bạn không thể. Khóa chính không được có trường rỗng.


1

Để khám phá bất kỳ ràng buộc nào được sử dụng, hãy sử dụng mã bên dưới:

-- Set the long data type for display purposes to 500000.

SET LONG 500000

-- Define a session scope variable.

VARIABLE output CLOB

-- Query the table definition through the <code>DBMS_METADATA</code> package.

SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual;

Về cơ bản, điều này cho thấy một câu lệnh tạo cho cách tạo bảng được tham chiếu. Khi biết cách tạo bảng, bạn có thể thấy tất cả các ràng buộc của bảng.

Câu trả lời lấy từ blog của Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ Từ lớp Thiết kế cơ sở dữ liệu của anh ấy.


0

Tôi đã gặp phải vấn đề tương tự khi cố gắng vượt qua một ràng buộc kiểm tra tùy chỉnh mà tôi cần cập nhật để cho phép các giá trị khác nhau. Vấn đề là ALL_CONSTRAINTS không có cách nào để biết (các) ràng buộc được áp dụng cho cột nào. Cách tôi quản lý để làm điều đó là bằng cách truy vấn ALL_CONS_COLUMNS thay vào đó, sau đó bỏ từng ràng buộc theo tên của chúng và tạo lại nó.

chọn tên_mạch từ all_cons_columns nơi table_name = [TABLE_NAME] và column_name = [COLUMN_NAME];


0

Điều gì đó tương tự đã xảy ra với tôi khi tôi tạo bản sao của cấu trúc vào bảng tạm thời, vì vậy tôi đã loại bỏ not null.

DECLARE
   CURSOR cur_temp_not_null IS
        SELECT table_name, constraint_name  FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND  owner='myUSUARIO';

   V_sql VARCHAR2(200); 

BEGIN
  FOR c_not_null IN cur_temp_not_null
   LOOP
     v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
     EXECUTE IMMEDIATE  v_sql;     
  END LOOP;
END;

Stack Overflow là một trang web chỉ có tiếng Anh. Tuy nhiên, có Stack Overflow en español . Xem bản chỉnh sửa của tôi.
help-info.de

0

Nếu ràng buộc trên cột STATUS được tạo mà không có tên trong quá trình tạo bảng, Oracle sẽ gán một tên ngẫu nhiên cho nó. Thật không may, chúng tôi không thể sửa đổi ràng buộc trực tiếp.

Các bước liên quan đến việc loại bỏ ràng buộc không tên được liên kết với cột STATUS

  1. Sao chép trường STATUS thành một trường mới STATUS2
  2. Xác định ràng buộc KIỂM TRA trên STATUS2
  3. Di chuyển dữ liệu từ STATUS sang STATUS2
  4. Thả cột TRẠNG THÁI
  5. Đổi tên STATUS2 thành STATUS

    ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN'; ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED')); UPDATE MY_TABLE SET STATUS2 = STATUS; ALTER TABLE MY_TABLE DROP COLUMN STATUS; ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.