create or replace package body pk_bank as
   procedure searchCard(
      v_cardid in varchar2,                    ------求教SQL语句哪错了,看了一天,还是没结果
      v_district in varchar2,
      v_statename in varchar2,
      v_username in varchar2,
      v_opendate in varchar2,
      v_cardref out bankref
   ) is
   v_sql varchar2(1000);
   begin
   v_sql:='select c.cardid,u.username,decode(c.savetype,0,''||活期||'',1,''||死期||'') as savetype,c.openmoney,s.statename,
          decode(c.moneytype,0,''||人民币||'',1,''||美金||'') as moneytype,c.accountmoney from cardinfo c,userinfo u,cardstate s where
           c.userid=u.userid and c.cardstate=s.stateid';
   if v_cardid is not null then
   v_sql:=v_sql||' and c.cardid='''||v_cardid||'';
   end if;
   if v_district is not null then
   v_sql:=v_sql||' and c.district='''||v_district||'';
   end if;
   if v_statename is not null then
   v_sql:=v_sql||' and s.statename='''||v_statename||'';
   end if;
   if v_username is not null then
   v_sql:=v_sql||' and u.username like''%'||v_username||'%''';
   end if;
   if v_opendate is not null then
   v_sql:=v_sql||' and to_char(c.opendate,''yyyymm'')='''||v_opendate||'';
   end if;
   --dbms_output.put_line(v_sql);
   open v_cardref for v_sql;
   close v_cardref;
   end searchCard;
end pk_bank;

解决方案 »

  1.   

    我没有细看你的SQL,但是我的第一感觉是你没有定义包.直接写的包体.
      

  2.   

    包有定义create or replace package pk_bank as
       type bankref is ref cursor;
       type cardrecord is record(
          cardid cardinfo.cardid%type,
          username userinfo.username%type,
          savetype varchar2(4),
          openmoney cardinfo.openmoney%type,
          statename cardstate.statename%type,
          moneytype varchar2(6),
          accountmoney cardinfo.accountmoney%type
       );
        procedure searchCard(
          v_cardid in varchar2,
          v_district in varchar2,
          v_statename in varchar2,
          v_username in varchar2,
          v_opendate in varchar2,
          v_cardref out bankref
       );
    end pk_bank;
    /
      

  3.   

    错误就是sql未正确结束,33行
      

  4.   

     open v_cardref for v_sql;
    这一句,
    是不是上面的V_sql写错了,我改来改去都不行,
      

  5.   

    对啊,我也是这么想,可是一改,连包体都建不成,
    两个decode写的对吗,大哥,还有, v_sql:=v_sql||' and c.cardid='''||v_cardid||'';
    如果改成  v_sql:=v_sql+' and c.cardid='''||v_cardid||'';
    包体也能建成,但是错误又变成 数值或值错误,字符到数值的转换错误这些错误都是我在用JAVA调这个存储过程的时候报的
      

  6.   

    在ORACLE SQL语句中,单引号和双引号的使用/**在ORACLE中 双引号" 被当做一个普通的字符串来处理**/
    SELECT '"' AS "字符串结果" FROM DUAL;
    /**正常状态下,两个''包含的字符串被当做字面值**/
    SELECT '[email protected]' FROM DUAL;
    /**测试一下三个单引号的情况  : ORA-01756:引号内的字符串没有正确结束**/
    --SELECT ''' FROM DUAL;
    /**测试一下四个单引号的情况 : 结果为一个 ' (单引号)  **/
    --说明 第二个单引号被ORACLE默认为是 转义字符
    SELECT '''' FROM DUAL;
    /**验证一下第二个单引号是转义字符的推断,在第二个和第三个单引号之间增加一个空格**/
    --提示错误:ORA-0092:未找到要求的FROM关键字 说明刚才的推论是对的
    SELECT '' '' FROM DUAL;
    /**在动态sql里面会经常用到单引号的,例如需要动态增加like,写一个测试的小例子**/
    DECLARE
        V_SQL VARCHAR2(200);
        N_COUNT NUMBER(4);
        V_NAME VARCHAR2(100);
    BEGIN
        V_NAME := '名字';
        V_SQL := 'SELECT COUNT(1) FROM T1 WHERE 1=1';
        V_SQL := CONCAT(V_SQL,' AND T1.NAME LIKE ''%'||V_NAME||'%''');
         EXECUTE IMMEDIATE V_SQL INTO N_COUNT;
         DBMS_OUTPUT.PUT_LINE('N_COUNT'||'==>'||N_COUNT);
    END;
    /**总结:
    1、在ORACLE中,双引号是被当做一个普通的字符串来处理的。
    2、在一对单引号包含的语句中,必须有一对相邻的单引号表示一个单引号
    3、两个相邻的单引号的作用,第一个是用来表示转义字符,后面一个表示真正的单引号
    **/
      

  7.   

    将if v_opendate is not null then
      v_sql:=v_sql||' and to_char(c.opendate,''yyyymm'')='''||v_opendate||'';
      end if;
    改成
    if v_opendate is not null then
      v_sql:=v_sql||' and to_char(c.opendate,''yyyymm'')='''||v_opendate||'''';
      end if;
      

  8.   

    v_sql: = v_sql||' and to_char(c.opendate,''yyyymm'')='''||v_opendate||'''';
    成对出现!
      

  9.   

    v_sql: = v_sql||' and to_char(c.opendate,''yyyymm'')='''||v_opendate||'''';
    成对出现!
    刚才标错了。