错误的参数数量或类型

时间:2018-09-30 07:19:50

标签: sql oracle plsql dynamic-sql

Create or replace procedure sp_create_tables as 
Lv_str varchar2(1000);
Begin
    For I in (select distinct(deptno) from emp) loop
    Lv_str:='create table deptno'||I||'  select * from emp where 
        1=2';
    Execute immediate lv_str;
    End loop;
End;

2 个答案:

答案 0 :(得分:4)

这行代码I中是一个隐式 rowtype 变量,其数据结构由驾驶选择语句的投影定义:

For I in (select distinct(deptno) from emp) loop

但是您试图在动态SQL中引用它,就像它是一个属性一样。您需要改用列名。

Create or replace procedure sp_create_tables as 
   Lv_str varchar2(1000);
Begin
    For I in (select distinct (deptno) from emp) loop
        Lv_str:='create table deptno'|| I.deptno ||
              ' as  select * from emp where  1=2';
        Execute immediate lv_str;
    End loop;
End;

偶然地,您的动态SQL语句中存在一个错误。正确的语法是CREATE TABLE ... AS SELECT ...。动态SQL很难,因为编译器无法验证字符串中的代码位。因此,应该是编译错误的东西会表现为运行时错误。您会发现使用一些日志记录(或dbms_output.put_line())来记录代码以在汇编语句运行之前对其进行记录是有帮助的。它使调试更加容易。


  

”“我收到一个错误,提示-01031权限不足”

因此,这意味着您通过角色授予了创建表的授权。 Oracle安全模型不允许我们使用通过角色授予的特权来构建PL / SQL程序或视图。这包括通过动态SQL执行DDL的PL / SQL。您需要一个DBA用户才能将CREATE TABLE直接授予您的用户。

答案 1 :(得分:4)

据我了解,您的问题可能是“为什么程序会引发此编译错误”

  

PLS-00306:调用'||'时参数的数量或类型错误

原因是隐式游标循环变量I引用了查询中的记录集,而不是deptno本身。为了引用deptno,您应该使用<loop_variable>.deptno。另外还应该更改2件事:as关键字丢失,DISTINCT是关键字,并且您将其用作函数,由于默认括号,该函数可以使用,但不是正确的使用方式它。

Create or replace procedure sp_create_tables as 
Lv_str varchar2(1000);
Begin
    For I in (select distinct dept from emp) loop
    Lv_str:='create table deptno'||I.deptno||' as select * from emp where 
        1=2';
    Execute immediate lv_str;
    End loop;
End;