在不知道 Oracle 名称的情况下删除索引或约束

发布于 2024-12-28 17:46:04 字数 2387 浏览 5 评论 0原文

在 Oracle 数据库上,我有一个外键,但不知道其名称,只知道列名和引用列名。 我想编写一个sql脚本,如果存在的话应该删除这个外键,所以这是我使用的代码:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
end;

这个脚本的输出是“匿名块完成”,所以它是成功的,但是当我添加删除部分时:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
 if (fName != '') THEN
  alter table MY_TABLE_NAME drop constraint fName;
 end if;
end;

然后我得到这个:

错误报告:ORA-06550:第 9 行,第 5 列:PLS-00103:遇到 当期望出现以下情况之一时,符号“ALTER”:

begin case 声明 goto 退出 ifloop mod null pragma raise 返回选择更新,同时使用 <<关闭当前删除 获取锁插入打开回滚保存点设置sql执行提交 forall合并管道 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:

谁能告诉我这里有什么问题吗?

我还尝试将所有内容放入一个函数中:

declare
  function getFName return varchar2 is
    fName varchar2(255 char);
  begin
   SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';

   return fName;
  end;
begin
  if getFName() != '' then
   alter table all_events drop constraint getFName(); 
  end if;
end; 

结果是由语句“alter table”引起的相同错误

这也没有帮助:

alter table all_events drop constraint
   (SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME');

输出是:

错误报告:SQL 错误:ORA-02250:约束名称缺失或无效 02250. 00000 - “约束名称缺失或无效” *原因:约束名称丢失或无效。 *操作:为约束名称指定有效的标识符名称。

对于 sql 服务器(MS SQL)来说,做到这一点非常容易。只需用 @ 声明一个变量并设置它,然后使用它即可。在 oracle 上我不知道它不起作用......

On a oracle database I have a foreign key, without knowing its name, just the column_name and the reference_column_name.
I want to write a sql script which should drop this foreign key if it exists, so this is the code I use:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
end;

The output of this script is "anonymous block completed", so it was successful, but when I add the drop part:

declare
 fName varchar2(255 char);
begin
 SELECT x.constraint_name into fName FROM all_constraints x
 JOIN all_cons_columns c ON
 c.table_name = x.table_name AND c.constraint_name = x.constraint_name
 WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';
 if (fName != '') THEN
  alter table MY_TABLE_NAME drop constraint fName;
 end if;
end;

Then I get this one:

Error report: ORA-06550: line 9, column 5: PLS-00103: Encountered the
symbol "ALTER" when expecting one of the following:

begin case declare exit for goto if loop mod null pragma raise
return select update while with << close current delete
fetch lock insert open rollback savepoint set sql execute commit
forall merge pipe
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

So can anyone tell me what is the problem here?

I also tried to put everything into a function:

declare
  function getFName return varchar2 is
    fName varchar2(255 char);
  begin
   SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME';

   return fName;
  end;
begin
  if getFName() != '' then
   alter table all_events drop constraint getFName(); 
  end if;
end; 

The result was the same error caused by the statement "alter table"

This one also did not help:

alter table all_events drop constraint
   (SELECT x.constraint_name into fName FROM all_constraints x
   JOIN all_cons_columns c ON
   c.table_name = x.table_name AND c.constraint_name = x.constraint_name
   WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME');

The output was:

Error report: SQL Error: ORA-02250: missing or invalid constraint name
02250. 00000 - "missing or invalid constraint name"
*Cause: The constraint name is missing or invalid.
*Action: Specify a valid identifier name for the constraint name.

For a sql server (MS SQL) there is so easy to do this. Just declaring a variable with @ and the set it, after that just use it. On oracle I don't have any clue what it isn't working...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧话新听 2025-01-04 17:46:04

您的原始版本大部分都很好,只是您不能直接在 PL/SQL 块中执行 DDL;相反,您必须将其包装在 EXECUTE IMMEDIATE 中:

execute immediate 'alter table MY_TABLE_NAME drop constraint "' || fName || '"';

即使约束名称在编译时已知,这也是正确的,但在您的情况下它是双重正确的,因为 fName< /code> 不是约束名称,而是包含约束名称的变量。

另外,这个:

if (fName != '') THEN

无效/没有意义,因为在 Oracle 中 '' 表示 NULL。你应该写

IF fName IS NOT NULL THEN

Your original version is mostly fine, except that you can't directly execute DDL in a PL/SQL block; rather, you have to wrap it in an EXECUTE IMMEDIATE:

execute immediate 'alter table MY_TABLE_NAME drop constraint "' || fName || '"';

This would be true even if the constraint-name were known at compile-time, but it's doubly true in your case, since fName isn't the constraint-name, but rather, a variable containing the constraint-name.

Also, this:

if (fName != '') THEN

is not valid/meaningful, since in Oracle '' means NULL. You should write

IF fName IS NOT NULL THEN

instead.

末が日狂欢 2025-01-04 17:46:04

这是删除列的所有类型为“R”的约束的方法:

begin
    FOR rec IN (SELECT x.constraint_name fName FROM all_constraints x
        JOIN all_cons_columns c ON
        c.table_name = x.table_name AND c.constraint_name = x.constraint_name
        WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME')
    LOOP
        EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE_NAME DROP CONSTRAINT "' || rec.fName || '"';
    END LOOP;
end;

This is how to drop all constraints typed "R" for a column:

begin
    FOR rec IN (SELECT x.constraint_name fName FROM all_constraints x
        JOIN all_cons_columns c ON
        c.table_name = x.table_name AND c.constraint_name = x.constraint_name
        WHERE x.table_name = 'MY_TABLE_NAME' AND x.constraint_type = 'R' AND c.column_name ='MY_COLUMN_NAME')
    LOOP
        EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE_NAME DROP CONSTRAINT "' || rec.fName || '"';
    END LOOP;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文