ฉันจะทิ้งข้อ จำกัด “ not null” ใน Oracle ได้อย่างไรเมื่อฉันไม่รู้ชื่อของข้อ จำกัด


85

ฉันมีฐานข้อมูลที่มีข้อ จำกัด NOT NULL บนฟิลด์และฉันต้องการลบข้อ จำกัด นี้ ปัจจัยที่ซับซ้อนคือข้อ จำกัด นี้มีชื่อที่กำหนดโดยระบบและชื่อของข้อ จำกัด นั้นแตกต่างกันระหว่างเซิร์ฟเวอร์ที่ใช้งานจริงเซิร์ฟเวอร์รวมและฐานข้อมูลของผู้พัฒนาต่างๆ กระบวนการปัจจุบันของเราคือการตรวจสอบสคริปต์การเปลี่ยนแปลงและงานอัตโนมัติจะดำเนินการค้นหาที่เหมาะสมผ่าน sqlplus กับฐานข้อมูลเป้าหมายดังนั้นฉันต้องการโซลูชันที่สามารถส่งตรงไปยัง sqlplus ได้โดยตรง

ในฐานข้อมูลของฉันเอง SQL ที่จะวางสิ่งนี้จะเป็น:

alter table MYTABLE drop constraint SYS_C0044566

ฉันสามารถเห็นข้อ จำกัด เมื่อฉันสอบถามall_constraintsมุมมอง:

select * from all_constraints where table_name = 'MYTABLE'

แต่ผมไม่แน่ใจว่าวิธีการทำงานร่วมกับSEARCH_CONDITION's LONGชนิดข้อมูลหรือวิธีการที่ดีที่สุดในการลบแบบไดนามิก จำกัด มองขึ้นแม้หลังจากที่ฉันรู้ว่าชื่อของมัน

ดังนั้นฉันจะสร้างสคริปต์การเปลี่ยนแปลงที่สามารถยกเลิกข้อ จำกัด นี้ตามสิ่งที่เป็นอยู่แทนที่จะเป็นชื่อของมันได้อย่างไร


แก้ไข: คำตอบของ @ Allan เป็นคำตอบที่ดี แต่ฉันกังวล (เนื่องจากฉันไม่มีความเชี่ยวชาญด้าน Oracle) ว่าอาจไม่เป็นความจริงในระดับสากลที่ข้อ จำกัด ใด ๆ ที่อาจมีชื่อที่ระบบสร้างขึ้นจะเกี่ยวข้องกับวิธีการลบ ข้อ จำกัด โดยไม่ต้องรู้ชื่อ เป็นความจริงหรือไม่ที่จะมีวิธีหลีกเลี่ยงไม่ให้ต้องรู้ชื่อข้อ จำกัด ที่ตั้งชื่อระบบเมื่อทิ้งข้อ จำกัด นั้นอย่างมีเหตุผล?


3
เพียงเพื่อตอบสนองความอยากรู้ของคุณ: ข้อ จำกัด NOT NULL เป็นประเภทข้อ จำกัดเดียวใน Oracle ที่คุณสามารถลบออกได้โดยไม่จำเป็นต้องทราบชื่อข้อ จำกัด ประเภทข้อ จำกัด อื่น ๆ ทั้งหมดที่คุณต้องทราบชื่อของข้อ จำกัด
Jeffrey Kemp

คำตอบ:


170
alter table MYTABLE modify (MYCOLUMN null);

ใน Oracle ข้อ จำกัด ที่ไม่มีค่าว่างจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อไม่ได้ระบุค่าว่างสำหรับคอลัมน์ ในทำนองเดียวกันค่าเหล่านี้จะถูกทิ้งโดยอัตโนมัติเมื่อเปลี่ยนคอลัมน์เพื่อให้เป็นโมฆะ

การชี้แจงคำถามที่แก้ไข : โซลูชันนี้ใช้เฉพาะกับข้อ จำกัด ที่สร้างขึ้นสำหรับคอลัมน์ "ไม่ใช่ค่าว่าง" หากคุณระบุ "คีย์หลัก" หรือขีด จำกัด ของการตรวจสอบในคำจำกัดความของคอลัมน์โดยไม่ต้องตั้งชื่อคุณจะได้ชื่อที่ระบบสร้างขึ้นสำหรับข้อ จำกัด (และดัชนีสำหรับคีย์หลัก) ในกรณีดังกล่าวคุณจำเป็นต้องทราบชื่อเพื่อวาง คำแนะนำที่ดีที่สุดคือหลีกเลี่ยงสถานการณ์โดยตรวจสอบให้แน่ใจว่าคุณระบุชื่อสำหรับข้อ จำกัด ทั้งหมดที่ไม่ใช่ "not null" หากคุณพบว่าตัวเองตกอยู่ในสถานการณ์ที่ต้องทิ้งข้อ จำกัด เหล่านี้โดยทั่วไปคุณอาจต้องใช้ PL / SQL และตารางนิยามข้อมูล


ดูเหมือนจะดีเกินไปที่จะเป็นจริง แต่มันจัดการเคสปัจจุบันของฉันได้อย่างแน่นอนและเรียบง่าย! มีกรณีใดบ้างใน Oracle ที่ชื่อข้อ จำกัด สามารถสร้างขึ้นโดยระบบได้ แต่ไม่สามารถเขียน sql เพื่อหลีกเลี่ยงชื่อข้อ จำกัด เช่นนั้นได้หรือไม่?
Chris Farmer

1
ขอบคุณ ... ปรากฎว่าnot nullข้อ จำกัด เป็นเพียงข้อ จำกัด ที่ตั้งชื่อระบบในสคีมาของฉันที่น่าจะส่งผลต่อฉันในลักษณะนี้
Chris Farmer


1

เพียงจำไว้ว่าหากฟิลด์ที่คุณต้องการทำให้เป็นโมฆะเป็นส่วนหนึ่งของคีย์หลักคุณจะทำไม่ได้ คีย์หลักต้องไม่มีฟิลด์ว่าง


1

หากต้องการค้นหาข้อ จำกัด ที่ใช้ให้ใช้รหัสด้านล่าง:

-- 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;

โดยพื้นฐานแล้วจะแสดงคำสั่งสร้างสำหรับวิธีสร้างตารางที่อ้างอิง เมื่อทราบวิธีสร้างตารางคุณจะเห็นข้อ จำกัด ของตารางทั้งหมดได้

คำตอบที่นำมาจากบล็อกของ Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/จากคลาส Database Design I ของเขา


0

ฉันประสบปัญหาเดียวกันกับการพยายามแก้ไขข้อ จำกัด ในการตรวจสอบแบบกำหนดเองที่ฉันต้องอัปเดตเพื่ออนุญาตค่าต่างๆ ปัญหาคือ ALL_CONSTRAINTS ไม่มีวิธีบอกว่าข้อ จำกัด ถูกนำไปใช้กับคอลัมน์ใด วิธีที่ฉันจัดการได้คือการค้นหา ALL_CONS_COLUMNS แทนจากนั้นจึงทิ้งข้อ จำกัด แต่ละข้อตามชื่อและสร้างขึ้นใหม่

เลือก constraint_name จาก all_cons_columns โดยที่ table_name = [TABLE_NAME] และ column_name = [COLUMN_NAME];


0

มีบางอย่างเกิดขึ้นกับฉันเมื่อฉันทำสำเนาโครงสร้างไปยังตารางชั่วคราวดังนั้นฉันจึงลบ 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 เป็นไซต์ภาษาอังกฤษเท่านั้น แต่มีกองมากเกิน en español ดูการแก้ไขของฉัน
help-info.de

0

หากข้อ จำกัด ของคอลัมน์ STATUS ถูกสร้างขึ้นโดยไม่มีชื่อในระหว่างการสร้างตาราง Oracle จะกำหนดชื่อแบบสุ่มให้ ขออภัยเราไม่สามารถแก้ไขข้อ จำกัด ได้โดยตรง

ขั้นตอนที่เกี่ยวข้องกับการทิ้งข้อ จำกัด ที่ไม่มีชื่อที่เชื่อมโยงกับคอลัมน์ STATUS

  1. ทำซ้ำช่อง STATUS ในฟิลด์ใหม่ STATUS2
  2. กำหนดข้อ จำกัด CHECK บน STATUS2
  3. ย้ายข้อมูลจาก STATUS ไปยัง STATUS2
  4. วางคอลัมน์ STATUS
  5. เปลี่ยนชื่อ STATUS2 เป็น 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;

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.