Sql 如何从表中查找列的约束名称,并使用单个查询将其删除
我需要找到一个列的约束名称,并用一条select语句将其删除。 如果不可能,那么替代方法是什么Sql 如何从表中查找列的约束名称,并使用单个查询将其删除,sql,oracle,plsql,oracle11g,Sql,Oracle,Plsql,Oracle11g,我需要找到一个列的约束名称,并用一条select语句将其删除。 如果不可能,那么替代方法是什么 我需要将此查询提供给另一个人,这样当他运行查询时,它将自动找到特定表的列的约束名称,然后将其删除。。没有硬编码的任何内容下面是一个示例-一个测试表,其中要删除NOTNULL约束 SQL> CREATE TABLE test 2 ( 3 id NUMBER PRIMARY KEY, 4 name VARCHAR2 (10) NOT NULL,
我需要将此查询提供给另一个人,这样当他运行查询时,它将自动找到特定表的列的约束名称,然后将其删除。。没有硬编码的任何内容下面是一个示例-一个测试表,其中要删除
NOTNULL
约束
SQL> CREATE TABLE test
2 (
3 id NUMBER PRIMARY KEY,
4 name VARCHAR2 (10) NOT NULL, --> this constraint should be dropped
5 sex VARCHAR2 (1) CHECK (sex IN ('Y', 'N'))
6 );
Table created.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069006 --> this one
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
SQL>
函数(由于用户约束的LONG
数据类型。搜索条件
,因此我们可以检查它是否为非空
函数):
接受表名和列名的过程;如果有notnull
约束,它将被删除。否则,什么也不会发生:
SQL> CREATE OR REPLACE PROCEDURE p_dropcon (par_table_name IN VARCHAR2,
2 par_column_name IN VARCHAR2)
3 IS
4 l_con user_cons_columns.constraint_name%TYPE;
5 BEGIN
6 SELECT a.constraint_name
7 INTO l_con
8 FROM user_constraints a
9 JOIN user_cons_columns b ON b.constraint_name = a.constraint_name
10 WHERE a.table_name = UPPER (par_table_name)
11 AND b.column_name = UPPER (par_column_name)
12 AND INSTR (UPPER (f_sc (a.constraint_name)), 'IS NOT NULL') > 0;
13
14 EXECUTE IMMEDIATE
15 'alter table '
16 || DBMS_ASSERT.sql_object_name (par_table_name)
17 || ' drop constraint '
18 || l_con;
19 EXCEPTION
20 WHEN NO_DATA_FOUND
21 THEN
22 -- There's no NOT NULL constraint on that column
23 NULL;
24 END;
25 /
Procedure created.
SQL>
测试:
SQL> EXEC p_dropcon('test', 'name');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
嗯,;已删除对NAME
列的约束。身份证怎么样
SQL> EXEC p_dropcon('test', 'id');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
SQL>
正如所料,什么也没发生
但是(虽然不太可能发生),如果您创建了自己的包含搜索字符串的检查约束,
不为NULL,例如
SQL> CREATE TABLE test
2 (
3 id NUMBER PRIMARY KEY,
4 name VARCHAR2 (10) NOT NULL,
5 sex VARCHAR2 (1) CHECK (sex IN ('IS NOT NULL')) --> this
6 );
Table created.
SQL>
并在该列上运行相同的过程,约束将被删除,尽管它不是您想要的:
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069012
TEST SEX SYS_C0069013
TEST ID SYS_C0069014
SQL> EXEC p_dropcon('test', 'sex');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069012
TEST ID SYS_C0069014
SQL>
结论:您不应该盲目地删除约束。下面是一个示例-一个测试表,其中包含要删除的notnull
约束
SQL> CREATE TABLE test
2 (
3 id NUMBER PRIMARY KEY,
4 name VARCHAR2 (10) NOT NULL, --> this constraint should be dropped
5 sex VARCHAR2 (1) CHECK (sex IN ('Y', 'N'))
6 );
Table created.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069006 --> this one
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
SQL>
函数(由于用户约束的LONG
数据类型。搜索条件
,因此我们可以检查它是否为非空
函数):
接受表名和列名的过程;如果有notnull
约束,它将被删除。否则,什么也不会发生:
SQL> CREATE OR REPLACE PROCEDURE p_dropcon (par_table_name IN VARCHAR2,
2 par_column_name IN VARCHAR2)
3 IS
4 l_con user_cons_columns.constraint_name%TYPE;
5 BEGIN
6 SELECT a.constraint_name
7 INTO l_con
8 FROM user_constraints a
9 JOIN user_cons_columns b ON b.constraint_name = a.constraint_name
10 WHERE a.table_name = UPPER (par_table_name)
11 AND b.column_name = UPPER (par_column_name)
12 AND INSTR (UPPER (f_sc (a.constraint_name)), 'IS NOT NULL') > 0;
13
14 EXECUTE IMMEDIATE
15 'alter table '
16 || DBMS_ASSERT.sql_object_name (par_table_name)
17 || ' drop constraint '
18 || l_con;
19 EXCEPTION
20 WHEN NO_DATA_FOUND
21 THEN
22 -- There's no NOT NULL constraint on that column
23 NULL;
24 END;
25 /
Procedure created.
SQL>
测试:
SQL> EXEC p_dropcon('test', 'name');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
嗯,;已删除对NAME
列的约束。身份证怎么样
SQL> EXEC p_dropcon('test', 'id');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST SEX SYS_C0069007
TEST ID SYS_C0069008
SQL>
正如所料,什么也没发生
但是(虽然不太可能发生),如果您创建了自己的包含搜索字符串的检查约束,不为NULL,例如
SQL> CREATE TABLE test
2 (
3 id NUMBER PRIMARY KEY,
4 name VARCHAR2 (10) NOT NULL,
5 sex VARCHAR2 (1) CHECK (sex IN ('IS NOT NULL')) --> this
6 );
Table created.
SQL>
并在该列上运行相同的过程,约束将被删除,尽管它不是您想要的:
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069012
TEST SEX SYS_C0069013
TEST ID SYS_C0069014
SQL> EXEC p_dropcon('test', 'sex');
PL/SQL procedure successfully completed.
SQL> SELECT table_name, column_name, constraint_name
2 FROM user_cons_columns
3 WHERE table_name = 'TEST';
TABLE_NAME COLUMN_NAM CONSTRAINT_NAME
------------------------------ ---------- ------------------------------
TEST NAME SYS_C0069012
TEST ID SYS_C0069014
SQL>
结论:您不应该盲目删除约束。只需在一个.sql脚本中向客户提供以下查询,客户只需更改表名即可
您还可以使用过程或其他已知的SQL执行方法来执行以下代码:
BEGIN
FOR I IN (
SELECT
TABLE_NAME,
COLUMN_NAME,
NULLABLE
FROM
USER_TAB_COLUMNS
WHERE
TABLE_NAME = 'TEST'
AND NULLABLE = 'N'
) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '
|| I.TABLE_NAME
|| ' MODIFY '
|| I.COLUMN_NAME
|| ' NULL ';
END LOOP;
END;
/
你可以看到这张照片
干杯 只需在一个.sql脚本中向客户提供以下查询,客户只需更改表名即可
您还可以使用过程或其他已知的SQL执行方法来执行以下代码:
BEGIN
FOR I IN (
SELECT
TABLE_NAME,
COLUMN_NAME,
NULLABLE
FROM
USER_TAB_COLUMNS
WHERE
TABLE_NAME = 'TEST'
AND NULLABLE = 'N'
) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '
|| I.TABLE_NAME
|| ' MODIFY '
|| I.COLUMN_NAME
|| ' NULL ';
END LOOP;
END;
/
你可以看到这张照片
干杯 什么样的约束?NOTNULL CONSTRAINTD您不只是想做alter table。。专栏。。。空
那么?你不需要知道系统生成的名称。我在问如何在不知道名称的情况下删除约束你不需要知道名称,这就是我所说的。您只需要表和列名;无论如何,你都必须知道这个名字。如果你做不到,我缺少什么?什么样的约束?NOTNULL CONSTRAINTD您不只是想做alter table。。专栏。。。空
那么?你不需要知道系统生成的名称。我在问如何在不知道名称的情况下删除约束你不需要知道名称,这就是我所说的。您只需要表和列名;无论如何,你都必须知道这个名字。如果你做不到,我还缺什么?