【问题标题】:Oracle Procedure to Drop a Table as Argument and recreate it删除表作为参数并重新创建它的 Oracle 过程
【发布时间】:2015-04-28 13:36:48
【问题描述】:

我正在尝试创建一个执行以下操作的 oracle 过程 transfer_table(table_name)

  1. table_name 放入schema_a
  2. schema_a 中创建table_name 作为table_name@schema_b 的(copyselect *?)

我需要这个过程是安全的:如果 table_name 在 schema_a 中不存在,仍然继续创建它作为 table_name@schema_b 的副本

这是我到目前为止的地方,但似乎效果不佳......

create or replace
PROCEDURE transfer_table
  (
      @pTableName  NVARCHAR(128)
  )
  IS

  BEGIN
      execute immediate 
          'DROP TABLE '|| pTableName;
      execute immediate
          'CREATE TABLE '||pTableName|| ' AS SELECT * FROM ' || pTableName || '@SCHEMA_B';

  END;

对我做事方式的任何帮助和任何优化都将不胜感激。真正的目标是将表从模式 B 复制到模式 A,作为一个过程

更新的代码 - 仍然无法正确编译:

create or replace
PROCEDURE transfer_table
  (
      table_name VARCHAR2(30)
  )
  IS
  BEGIN
    BEGIN
      execute immediate 
          'DROP TABLE '|| table_name;    
      WHEN OTHERS THEN
        IF SQLCODE != -942 THEN
          RAISE;
        END IF;
          end;
    END;
        EXECUTE IMMEDIATE
          'CREATE TABLE '||table_name|| ' AS SELECT * FROM ' || table_name || '@SCHEMA_B';

  END;
  /

【问题讨论】:

  • 你已经使用oracle 进行了标记,但你编写的似乎是 PL/SQL 和 T-SQL 的混合体
  • @Sathya - 那我真的迷路了。这是甲骨文的,我一直在网上搜索,可能拿错了……

标签: oracle stored-procedures plsql


【解决方案1】:

pTableName || '@SCHEMA_B'

这是不正确的。您需要将架构中的表称为SCHEMA.TABLE_NAME

关于你的脚本,让我们一步一步看:

我是用户 Lalit,我想创建一个表 EMP 作为来自 SCOTT 模式的同一个表的副本。

SQL> SHOW USER
USER is "LALIT"
SQL> SELECT * FROM lalit.emp;
SELECT * FROM lalit.emp
                    *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select count(*) from SCOTT.EMP;

  COUNT(*)
----------
        14

因此,它确认 EMP 表不在用户 LALIT 中,它在 SCOTT 中。我现在将创建它:

SQL> DECLARE
  2  table_name VARCHAR2(30);
  3  schema_name varchar2(30);
  4  BEGIN
  5  table_name:='EMP';
  6  schema_name:='SCOTT';
  7  begin
  8   EXECUTE IMMEDIATE
  9            'DROP TABLE '|| table_name;
 10            EXCEPTION
 11     WHEN OTHERS THEN
 12        IF SQLCODE != -942 THEN
 13           RAISE;
 14        END IF;
 15            end;
 16        EXECUTE IMMEDIATE
 17            'CREATE TABLE '||table_name|| ' AS SELECT * FROM ' || schema_name||'.'||table_name || '';
 18  END;
 19  /

PL/SQL procedure successfully completed.

让我们确认一下:

SQL> select count(*) from lalit.emp;

  COUNT(*)
----------
        14

SQL>

所以,我现在在模式 LALIT 中拥有表 EMP。

【讨论】:

  • 嗨 - 实际上,我使用 @SCHEMA_B 因为它是一个 DBLink...我应该在之前说过...
  • @Stephane 的变量声明@pTableName NVARCHAR(128) 也不正确——第一个字符应该没有@ 符号,应该是nvarchar2
  • @Stephane,如果另一个对象在不同的​​数据库中,您可以使用 dblink。但是,您确定您没有将架构称为数据库吗?因为我看到 SQL Server 开发人员对此感到困惑。
  • 确定是 dblink!
  • 但是如果它真的是一个不同的数据库,那么你可以将它称为schema.table@dblink。脚本没有太大变化,只需将@dblink 放在表格末尾即可。如果对您有帮助,请将其标记为已回答。
【解决方案2】:

您的更新代码有一些问题 - 参数参数不需要 varchar 的长度。还有一个额外的结尾。嵌套匿名块没有 EXCEPTION 关键字

应该是这样的:

CREATE OR REPLACE PROCEDURE transfer_table(table_name IN VARCHAR2) IS
BEGIN
  BEGIN
    EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
  EXCEPTION
    WHEN OTHERS THEN
      IF SQLCODE != -942 THEN
        RAISE;
      END IF;
  END;

  EXECUTE IMMEDIATE 'CREATE TABLE ' || table_name || ' AS SELECT * FROM ' || table_name || '@SCHEMA_B';
END transfer_table;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多