前一阵子做了一个工具,需要支持多种数据库,其中必须有Oracle,对Oracle接触不多,恶补了一阵子,只能了解些皮毛。下面是问题:
Oraclede 环境中,客户那边提出,执行存储过程时出错,信息:DBCustomException: ORA-00900: invalid SQL statement关于这个问题之前也遇到过,一直找不到原因,没解决,时好时坏,,由于客户大部分是SQL Server,也就没太在意,现在终于麻烦来了。我用自己创建的用户,通过P/L SQL 登陆,执行以下语句
--创建表
 create table ttt
 (
    aa varchar(20)
 )
 
 --创建存储过程
 CREATE OR REPLACE PROCEDURE   myproc  
  AS  BEGIN  
  select * from ttt;
 END 
 --执行
 exec myproc 执行存储过程时,开始报错:ORA-00900:无效SQL语句 (上面那个错误的中文版-_-!)
这时候看右边的存储过程如下,有个红叉,编译也不成功。我修改存储过程
 CREATE OR REPLACE PROCEDURE   myproc  
  AS 
BB VARCHAR(20);
 BEGIN  
  select aa into BB from ttt;
 END;然后那个红叉就没了但是执行还是出错 exec myproc ,提示无效的sql语句问了周围几个同事,竟然没人知道原因,无奈了,百度了一下也没有解决方法。请各位路过的高手解救我吧!ORZ为什么写select时会编译都不成功,又为什么我执行这俩种都会抱错,而且,我后来使用system登陆,重新操作了一遍,还是一样。

解决方案 »

  1.   

    补充一下,直接执行select 查询语句是没有问题的。
      

  2.   

    如果你在存储过程里要返回结果集的话要用游标oracle存储过程不用select * from tb 
    一定要有into
    select aa into v_var from tb 
    如果你的查询出来的aa是一个值的话 你可以用一个简单的变量来接收 类型要一致如果查询出来的aa是多个值的话 那就要用游标或者是复合变量了接收了
      

  3.   

    恩,支持下zhuomingwang,需要使用游标返回查询结果。google下sys_refcursor
      

  4.   

    oracle 存储过程 
    select 语句 必须返回数据
    比如用游标  select .. into 游标 from ...
    或用临时表
    insert into ...
    select .. from ..
      

  5.   


    你还是没明白  还是在用MSSQL 的写法 返回结果集在ORACLE 的使用游标 临时表 以及基于对象的数组来返回结果集这里我就以游标来弄CREATE OR REPLACE PROCEDURE myproc(cur out sys_refcursor)
     
      AS 
    BEGIN   
    open cur  select * from ttt;
    end;var cur sys_refcursor
    exec myproc(:cur)
    print cur
      

  6.   

    存储过程是不能只执行查询的。  一定要 select into 或者做点其他的操作。
      

  7.   

    Oracle的存储过程不能直接通过select来返回结果集,正如楼上各位说的,要返回结果集可以用游标,或用select ... into 子句。我发现你的存储过程中的变量BB的类型是VARCHAR(20),改成VARCHAR2(20)试试。Oracle的写法要多个2.
      

  8.   

    oracle返回结果集是要用游标的。不像mssqlserver一样的。
      

  9.   

    感谢大家,恶补了两天Oracle知识,终于把存储过程的问题搞通了。现在我的存储过程改为以下样子就可以正常用了。
    给后来的同学们参考:
    --创建
    create or replace procedure Data_list
       (  p_myPara varchar2  
       , p_ReCursor0 OUT sys_refcursor )
    AS
    begin 
        open  p_ReCursor0  for select   AA from ttt;
    end   Data_list;--执行
    begin
      -- 调用
      data_list(p_mypara => :p_mypara,
                p_recursor0 => :p_recursor0);
    end;结贴散分喽