0

目前我正在使用

    def PARAM1=&1
    def PARAM2=&2
    def PARAM3=&3
    DECLARE &PARAM4 VARCHAR(20);
    BEGIN
        PARAM4 := &PARAM1 || '2';
        CREATE TABLE &param4 AS SELECT * FROM &param1 Order By &param2,&param3;
    END;
    /
    exit;

我正在尝试运行它,但它给了我一个错误作为无效的 SQL 语句。我会使用 SQLPlus 从 shell 调用过程。

4

1 回答 1

3

您不需要匿名 PL/SQL 块;在其中您必须使用execute immediate,因为您不能将 DDL 作为本机命令执行。

这与我认为的等效:

def PARAM1=&1
def PARAM2=&2
def PARAM3=&3
def PARAM4=&PARAM1.2
CREATE TABLE &param4 AS SELECT * FROM &param1 Order By &param2,&param3;
exit;

您附加&PARAM1的固定值之间的句点标记变量 name 的结尾。没有它,将被解释为一个新参数。我猜这可能是导致您出现问题的原因。2&PARAM12

如果我使用参数t4,运行它idname我会得到(使用set verify on):

old:def PARAM1=&1
new:def PARAM1=t4
old:def PARAM2=&2
new:def PARAM2=id
old:def PARAM3=&3
new:def PARAM3=name
old:def PARAM4=&PARAM1.2
new:def PARAM4=t42
old:CREATE TABLE &param4 AS SELECT * FROM &param1 Order By &param2,&param3
new:CREATE TABLE t42 AS SELECT * FROM t4 Order By id,name

所以它执行的最后一条语句是:

CREATE TABLE t42 AS SELECT * FROM t4 Order By id,name

或者你可以在没有显式define命令的情况下做同样的事情:

CREATE TABLE &&1.2 AS SELECT * FROM &&1 Order By &&2,&&3;
exit;

order by子句在 CTAS 语句中没有多大意义,因为新表中的数据没有固有顺序,但它是有效的语法。


如果您真的想在匿名块中执行此操作,则必须将其包装在 中execute immediate,但除非您计划围绕它进行一些其他逻辑,否则没有意义:

BEGIN
    execute immediate 'CREATE TABLE &param1.2 AS SELECT * FROM '
      || ' &param1 Order By &param2,&param3';
END;
/
于 2013-09-24T08:56:16.213 回答