过程中的动态sql错误

Posted

技术标签:

【中文标题】过程中的动态sql错误【英文标题】:dynamic sql errors in procedure 【发布时间】:2012-11-22 04:25:06 【问题描述】:

为什么我的动态 sql 过程不起作用?我要做的就是从表格中显示一个简单的列。我收到以下错误:

第 1 行的错误: ORA-06550:第 1 行,第 7 列: PLS-00905:对象 SYSTEM.JOIN 无效 ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略

 create or replace procedure join
(p_table1 in varchar2,
p_joincolumn1 in varchar2,
p_joincolumn2 in varchar2)
 AS
lv_query varchar2(500);
lv_cursor number;
lv_col1 VARCHAR2(30);
lv_col2 VARCHAR2(30);
loopcount number:=0;
cursor_return_value integer;
 begin
lv_cursor:=dbms_sql.open_cursor;
dbms_output.put_line('Value assigned to cursor= ' || lv_cursor );
lv_query:='select p_joincolumn1 from p_table1';
dbms_output.put_line(lv_query);
dbms_sql.parse(lv_cursor, lv_query, dbms_sql.native);
dbms_sql.define_column (lv_cursor, 1, lv_col1);
dbms_sql.define_column (lv_cursor, 2, lv_col2);
cursor_return_value := dbms_sql.execute (lv_cursor);
LOOP
    loopcount:=loopcount+1;
    dbms_output.put_line('loopcount= ' || loopcount );
    if dbms_sql.fetch_rows (lv_cursor)=0 then
        EXIT;
    end if;

    dbms_sql.column_value(lv_cursor, 1, lv_col1);
    dbms_sql.column_value (lv_cursor, 2, lv_col2);
    dbms_output.put_line(lv_col1 || '   ' || lv_col2 ); 
END LOOP;
 dbms_output.put_line('At end of loop');
 dbms_sql.close_cursor(lv_cursor);
 end;
 /

 execute join ('PROJECT', 'PROJECT.P_ID', 'PROJECT.SKILL_ID');

错误:

 Procedure created.

 SQL> 
 SQL> execute testing_j ('PROJECT', 'PROJECT.P_ID', 'PROJECT.SKILL_ID');
 Value assigned to cursor= 20
 select p_joincolumn1 from p_table1
 BEGIN testing_j ('PROJECT', 'PROJECT.P_ID', 'PROJECT.SKILL_ID'); END;

 *
 ERROR at line 1:
 ORA-00942: table or view does not exist
 ORA-06512: at "SYS.DBMS_SYS_SQL", line 906
 ORA-06512: at "SYS.DBMS_SQL", line 39
 ORA-06512: at "SYSTEM.TESTING_J", line 17

【问题讨论】:

尝试在没有execute join ('PROJECT', 'PROJECT.P_ID'); 的情况下运行它,然后运行show errors。顺便说一句,这是-lv_col2 VARCHAR2(30;) 错字吗?如果不是,这可能是您的问题 - 应该是 lv_col2 VARCHAR2(30); 【参考方案1】:

该过程可能是用编译错误创建的。

尽量不要同时运行这两个命令- 1. 创建过程 - 如果创建过程中有错误,您可以使用命令show err 显示它们(在 sqlplus 中)(您可以查看如何查看错误 here) 2. 执行程序

至于您的代码: 在声明部分你有一行

lv_col2 VARCHAR2(30;)

应该是

lv_col2 VARCHAR2(30);

这可能是编译错误。

顺便说一句,恕我直言,用关键字 (join) 命名您的程序是不好的做法

【讨论】:

我修正了错字并且编译的代码没有错误。我编辑了我的帖子以显示我收到的确切错误。 @user1084561 - 是的,但您没有包含代码的修订版本。【参考方案2】:

哪一点

ORA-00942: table or view does not exist

让你感到困惑吗?您的数据库中没有名为 P_TABLE1 的表,或者 SYSTEM 模式中没有名为 P_TABLE1 的表。数据库对象名称仅在模式中是唯一的:如果我们想要引用由不同用户拥有的对象,我们需要在对象名称前加上该模式:

select p_joincolumn1 from user23.p_table1

此外,该用户需要授予我们对其对象的必要权限...

...除了 SYS 和 SYSTEM 等用户之外,强大的帐户具有完整的 ANY 权限。您不应该在 SYSTEM 模式中创建对象,因为它是 Oracle 系统的一个组成部分,并且使用它可能会损坏您的数据库。

【讨论】:

【参考方案3】:

修复了我的代码,现在可以使用了。将 dbms_sql.native 更改为 dbms_sql.v7,并且还更改了一些语法。

create or replace procedure testing_j
(table_name in varchar2,
column1 in varchar2)
AS
lv_query varchar2(500);
lv_cursor number;
lv_col1 number(6);
loopcount number:=0;
cursor_return_value integer;
begin
lv_cursor:=dbms_sql.open_cursor;
dbms_output.put_line('Value assigned to cursor= ' || to_char(lv_cursor));
lv_query:='SELECT ' || column1 || ' FROM ' || table_name;
dbms_output.put_line(lv_query);
dbms_sql.parse(lv_cursor, lv_query, dbms_sql.v7);



dbms_sql.define_column (lv_cursor, 1, lv_col1);
cursor_return_value := dbms_sql.execute (lv_cursor);
LOOP
    loopcount:=loopcount+1;
    --dbms_output.put_line('loopcount= ' || loopcount );
    if dbms_sql.fetch_rows (lv_cursor)=0 then
        EXIT;
    end if;

    dbms_sql.column_value(lv_cursor, 1, lv_col1);
    dbms_output.put_line(lv_col1);  
END LOOP;
dbms_output.put_line('At end of loop');
dbms_sql.close_cursor(lv_cursor);
end;
/


PL/SQL procedure successfully completed.

SQL> execute testing_j ('PROJECT', 'PROJECT.P_ID');
Value assigned to cursor= 12
SELECT PROJECT.P_ID FROM PROJECT
1
1
2
3
3
4
4
5
5
6
7
7
At end of loop

PL/SQL procedure successfully completed.

【讨论】:

以上是关于过程中的动态sql错误的主要内容,如果未能解决你的问题,请参考以下文章

存储过程中的动态 SQL 不返回结果集;在 SSMS 中运行时,我得到了结果

我在动态 sql 中找不到错误

动态 SQL 结果到 SQL 存储过程中的临时表中

Oracle:使用 SQL 或 PL/SQL 查找动态 SQL 中的错误位置

在动态 sql 中使用集合

创建一个表,其中动态 PL/SQL 中的“日期条件”