【问题标题】:Simple PL/SQL to check if table exists is not working检查表是否存在的简单 PL/SQL 不起作用
【发布时间】:2014-06-29 16:31:56
【问题描述】:

我正在将一些存储过程从 Sybase TSQL 转换为 Oracle PL/SQL,我已经遇到了一个我正在努力解决的问题!

下面的代码不会运行:

DECLARE

t INT := 0;
t_error EXCEPTION;
v_line VARCHAR2(100);

BEGIN

SELECT COUNT(*) INTO t FROM user_tables WHERE table_name = UPPER('tbl_BSUK_PriceIssue');

IF t = 1 THEN
  EXECUTE IMMEDIATE 'DROP TABLE tbl_BSUK_PriceIssue';
  t := 0;
  SELECT COUNT(*) INTO t FROM user_tables WHERE table_name = UPPER('tbl_BSUK_PriceIssue');
  IF t = 1 THEN
    RAISE t_error;
  END IF;
END IF;

EXCEPTION
  WHEN t_error THEN
  v_line := '<<< FAILED DROPPING table tbl_BSUK_PriceIssue >>>';
  dbms_output.put_line (v_line);
  WHEN OTHERS THEN
    v_line := '<<< Unknown Error >>>';
    dbms_output.put_line (v_line);
  END;


END;

我收到以下错误消息,我做错了什么?!

从第 17 行开始的错误命令 - DECLARE

t INT := 0; t_error 异常; v_line VARCHAR2(100);

开始

SELECT COUNT(*) INTO t FROM user_tables WHERE table_name = UPPER('tbl_BSUK_PriceIssue');

IF t = 1 THEN IMMEDIATE 'DROP TABLE tbl_BSUK_PriceIssue';
t := 0; SELECT COUNT(*) INTO t FROM user_tables WHERE table_name = UPPER('tbl_BSUK_PriceIssue');如果 t = 1 那么 提高 t_error;万一;如果结束;

当 t_error THEN v_line := '>>'; dbms_output.put_line (v_line);什么时候 其他人然后 v_line := '>>'; dbms_output.put_line (v_line);结尾; 结尾;错误报告 - ORA-06550:第 30 行,第 1 列:PLS-00103:遇到符号“END” 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:

我实际上是在尝试用 PL/SQL 版本替换以下 TSQL:

-- Create temp table for relevant trev_id's 
IF OBJECT_ID('dbo.tbl_BSUK_PriceIssue') IS NOT NULL
BEGIN
    DROP TABLE dbo.tbl_BSUK_PriceIssue
    IF OBJECT_ID('dbo.tbl_BSUK_PriceIssue') IS NOT NULL
        PRINT '<<< FAILED DROPPING TABLE dbo.tbl_BSUK_PriceIssue >>>'
    ELSE
        PRINT '<<< DROPPED TABLE dbo.tbl_BSUK_PriceIssue >>>'
END
go

【问题讨论】:

  • 你是通过sqlplus执行的吗?
  • 我正在使用 SQL Developer。

标签: sql oracle plsql


【解决方案1】:

我不知道这个错误,但你可以用一小部分代码做你想做的事。如果使用EXISTS(),则不需要计数变量,并且不需要EXECUTE IMMEDIATE,因为命令中没有变量数据:

IF 1 = (SELECT 1 FROM user_tables WHERE table_name = 'TBL_BSUK_PRICEISSUE') THEN
  DROP TABLE tbl_BSUK_PriceIssue;
  IF 1 = (SELECT 1 FROM user_tables WHERE table_name = 'TBL_BSUK_PRICEISSUE') THEN
    RAISE EXCEPTION;
  END IF;
END IF;

【讨论】:

  • 我投了这个票,但是当我尝试上面的代码时,我得到“无效的 SQL 语句”
  • 事实上下面的只是不会运行WTF?! IF EXISTS(SELECT 1 FROM user_tables WHERE table_name = 'tbl_BSUK_PriceIssue') THEN DROP TABLE tbl_BSUK_PriceIssue;如果结束;
  • 在 PL/SQL 中对我不起作用:PLS-00204:函数或伪列“EXISTS”只能在 SQL 语句中使用
  • 是的,这绝对不是 PL/SQL。
【解决方案2】:

尝试删除此部分中的END;

 WHEN OTHERS THEN
    v_line := '<<< Unknown Error >>>';
    dbms_output.put_line (v_line);
 END;

UPD。其实,你可以做的更短一点,drop后不需要检查表是否存在

declare
  eTableNotExists exception;
  pragma exception_init(eTableNotExists, -00942);
begin
    EXECUTE IMMEDIATE 'DROP TABLE tbl_BSUK_PriceIssue';  
    dbms_output.put_line('<<< DROPPED TABLE dbo.tbl_BSUK_PriceIssue >>>');
exception 
  when eTableNotExists then null
  when others then    
    dbms_output.put_line ('<<< Unknown Error >>>' || sqlerrm);
end;
/

【讨论】:

  • 感谢 Dmitry,但请查看我的原始帖子(我在底部添加了一些进一步的信息),这样您就可以看到我要替换的内容。您的较短版本更优雅,但我不确定它的行为方式与 TSQL 版本相同吗?
  • 我的版本尝试删除表,如果它不存在,它什么也不做:) 无论如何,我很高兴我们解决了你的问题 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 2010-10-02
  • 2011-07-21
相关资源
最近更新 更多