查看: 8831|回复: 5

ORA-01722:无效数字(存储过程中出这个错误,比较蹊跷)

[复制链接]
论坛徽章:
1
优秀写手
日期:2014-07-22 06:00:13
跳转到指定楼层
1#
发表于 2011-5-29 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CREATE OR REPLACE PROCEDURE "P_INSERTT_USER"(IUSERNAME    VARCHAR2,
                                             IUSERDEF     VARCHAR2,
                                             IPASSWORD    VARCHAR2,
                                             IUSERTYPE    NUMBER,
                                             ICORPID      NUMBER,
                                             IADMINERID   NUMBER,
                                             ICUSTOMERID  NUMBER,
                                             ITEAMID      VARCHAR2, --车队ID,以逗号分隔                                             ILINKTEL     VARCHAR2,
                                             IEMAIL       VARCHAR2,
                                             ILINKADDERSS VARCHAR2,
                                             IHYCAR       NUMBER,
                                             IPARENTID    NUMBER,
                                             OPRO_CODE    OUT NUMBER, --错误吗
                                             OPRO_DESC    OUT VARCHAR2 --错误描述
                                             ) AS
BEGIN
  DECLARE
    IUSERID  NUMBER;
    IUNITIDS CLOB; --以逗号分隔的车台ID字符串
  BEGIN
    OPRO_CODE := -1;
    OPRO_DESC := '';
    IF (IUSERNAME IS NULL OR IUSERDEF IS NULL OR IPASSWORD IS NULL OR
       IUSERTYPE IS NULL) THEN
      OPRO_CODE := -1;
      OPRO_DESC := '传输数据不合法!';
    ELSE
      SELECT SNT_USER.NEXTVAL INTO IUSERID FROM DUAL;
      INSERT INTO T_USER
        (USERID,
         USERNAME,
         USERDEF,
         PASSWORD,
         USERTYPE,
         CORPID,
         ADMINERID,
         STAMP,
         LINKTEL,
         EMAIL,
         LINKADDERSS,
         HYCAR,
         PARENTID)
      VALUES
        (IUSERID,
         IUSERNAME,
         IUSERDEF,
         IPASSWORD,
         IUSERTYPE,
         ICORPID,
         IADMINERID,
         SYSDATE,
         ILINKTEL,
         IEMAIL,
         ILINKADDERSS,
         IHYCAR,
         IPARENTID);
   
      IF ((ITEAMID IS NOT NULL) AND (ITEAMID <> '-1')) THEN
        IUNITIDS := '';
        FOR V IN (SELECT DISTINCT T.UNITID, T.TEAMID
                    FROM T_USER_CAR T
                   WHERE T.TEAMID IN (ITEAMID)) LOOP
          IUNITIDS := IUNITIDS || V.UNITID || ',';
        END LOOP;
        IF (IUNITIDS <> '') THEN
          IUNITIDS := SUBSTR(IUNITIDS, 1, LENGTH(IUNITIDS) - 1);
        END IF;
      
        P_INSERTT_CUSTOMER_UNIT_HERIT(IUSERID, IUNITIDS, 1, IPARENTID);
      
      END IF;
   
      COMMIT;
      OPRO_CODE := IUSERID;
      OPRO_DESC := '添加用户成功!';
    END IF;
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        ROLLBACK;
        OPRO_CODE := -1;
        OPRO_DESC := SQLERRM || ',' || OPRO_DESC;
      END;
  END;
END;


说明:T_USER_CAR 表中的TEAMID是NUMBER类型。

我直接在PL/SQL中执行
SELECT DISTINCT T.UNITID, T.TEAMID
                    FROM T_USER_CAR T
                   WHERE T.TEAMID IN (1300,1850)
是事以成功执行的,但我通过存储过程传过来就不行了,谁能告诉我为什么,怎么处理呀?谢谢



[ 本帖最后由 冷月宫主 于 2011-5-29 17:16 编辑 ]
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
2#
发表于 2011-5-29 17:47 | 只看该作者
你的sql里是静态字段,两个值,在pl/sql里是字符串,一个值啊,字符串遇到数字,转为数字,但是转不了,所以报错
T.TEAMID IN (ITEAMID)
类似于t.teadmid in ('1,2')了,当然和sql不一样

这个问题比较典型,很多方法,一般用自定义函数+table函数搞定
http://www.itpub.net/viewthread.php?tid=1228883&extra=&highlight=sql%D6%D0%D2%BB%B8%F6%D7%D6%B7%FB%B4%AE%B5%C4in-list%C5%D0%B6%CF%CE%CA%CC%E2&page=1

使用道具 举报

回复
论坛徽章:
57
SQL极客
日期:2013-12-09 14:13:35秀才
日期:2016-01-21 13:42:39秀才
日期:2016-01-13 12:14:26SQL大赛参与纪念
日期:2016-01-13 10:32:19SQL数据库编程大师
日期:2016-01-13 10:30:43秀才
日期:2015-12-14 14:47:54秀才
日期:2015-10-19 15:50:392015年新春福章
日期:2015-03-06 11:58:18懒羊羊
日期:2015-03-04 14:52:11优秀写手
日期:2014-11-08 06:00:14
3#
发表于 2011-5-29 18:02 | 只看该作者
CREATE TABLE TEST_CHAR2
(
A VARCHAR2(100)
);
INSERT INTO TEST_CHAR2
VALUES ('1300,1850');
COMMIT;
SELECT * FROM TEST_CHAR2
WHERE 1300 IN A ;
--报错,转换错误
SELECT to_number(CASE WHEN LEVEL=1 THEN SUBSTR(a,1,Instr(A, ',', 1, 1)-1)
       ELSE  SUBSTR(a,Instr(A, ',', 1, LEVEL-1)+1,Instr(A, ',', 1, LEVEL)-Instr(A, ',', 1, LEVEL-1)-1) END) FROM
(SELECT a||',' a FROM TEST_CHAR2) TEST_CHAR2
CONNECT BY LEVEL<= LENGTH(A)-LENGTH(Replace(A, ',', ''));
--现写了一个,用在逗号小于200的情况
with va as
( select 1300 id from dual
union all select 1850 from dual
)
select id from va where id in
(SELECT to_number(CASE WHEN LEVEL=1 THEN SUBSTR(a,1,Instr(A, ',', 1, 1)-1)
       ELSE  SUBSTR(a,Instr(A, ',', 1, LEVEL-1)+1,Instr(A, ',', 1, LEVEL)-Instr(A, ',', 1, LEVEL-1)-1) END) FROM
(SELECT a||',' a FROM TEST_CHAR2) TEST_CHAR2
CONNECT BY LEVEL<= LENGTH(A)-LENGTH(Replace(A, ',', '')))
--这样就不报错了

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-07-22 06:00:13
4#
 楼主| 发表于 2011-5-29 18:12 | 只看该作者
非常感谢,我看看,看样子是我根本没有弄明白,我先看看,好象有人处理过这种问题!

http://macrochen.iteye.com/blog/260249
http://**/viewthread.php?tid=1533
http://blog.csdn.net/wh62592855/archive/2011/01/05/6118673.aspx

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
5#
发表于 2011-5-29 18:15 | 只看该作者
1.首先搞清楚你的pl/sql的语句和你的sql语句根本就是不同的。pl/sql里是一个字符串,而不是value list
2.想办法把字符串切分为value list:方法很多,正则,自定义函数,sys_context,instr+substr配合一些hint

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-07-22 06:00:13
6#
 楼主| 发表于 2011-5-29 19:30 | 只看该作者
问题已解决,感谢楼上朋友!

http://blog.csdn.net/E_wsq/archive/2011/05/29/6453359.aspx

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表