错误 ORA-06502:PL/SQL:数字或值错误:字符到数字的转换错误 ORA-06512:在第 22 行
Posted
技术标签:
【中文标题】错误 ORA-06502:PL/SQL:数字或值错误:字符到数字的转换错误 ORA-06512:在第 22 行【英文标题】:Error ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at line 22 【发布时间】:2015-12-18 03:07:41 【问题描述】:我尝试了两天解决这个问题,但我无法解决。 我知道代码为什么会发生,但我不确定在哪里。 或者为什么会这样……
这必须在 PLSQL 中完成 这是家庭作业。
SET SERVEROUTPUT ON
DECLARE
V_IDNO PAYDATA1.IDNO%TYPE;
V_NAME PAYDATA1.NAME%TYPE;
V_SAL PAYDATA1.SALARY%TYPE;
V_JOB PAYDATA1.JOBCODE%TYPE;
V_PAY PAYDATA1.PAYHR%TYPE;
V_IDNO1 PAYTRAN1.IDNO%TYPE;
V_HOURSWK PAYTRAN1.HOURSWK%TYPE;
V_HOURS HOURSWKD.HOURSWK%TYPE;
V_CHECK NUMBER(10);
CURSOR paydata_cursor IS
SELECT IDNO, NAME, JOBCODE, SALARY, PAYHR FROM PAYDATA1
ORDER BY IDNO;
CURSOR paytran_cursor IS
SELECT IDNO, HOURSWK FROM PAYTRAN1
WHERE V_IDNO = IDNO
order by IDNO;
BEGIN
OPEN paydata_cursor;
LOOP
FETCH paydata_cursor INTO V_IDNO, V_NAME, V_CHECK, V_JOB, V_PAY;
EXIT WHEN paydata_cursor%NOTFOUND;
IF V_SAL > 0 THEN
V_CHECK := V_SAL / 52;
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
END IF;
IF V_SAL = 0 AND V_HOURSWK < 41 THEN
V_CHECK := V_PAY * V_HOURS;
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
ELSIF V_SAL = 0 AND V_HOURSWK > 40 THEN
V_CHECK := V_PAY * V_HOURS;
V_CHECK := V_SAL + ((V_HOURSWK * 1.5) * (V_HOURSWK - 40));
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
END IF;
END LOOP;
CLOSE paydata_cursor;
END;
/
SET SERVEROUTPUT OFF
我遇到了这个错误,整天都在尝试修复它,但无法解决。有什么建议吗?
SQL> @ CURSOR5
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 22
【问题讨论】:
你要写的是存储过程吗? 我们不能简单地在 PAYDATA1 和 PAYTRAN1 表之间进行连接吗? 【参考方案1】:问题是您的列paydata1.JOBCODE
不是数字
在此代码FETCH paydata_cursor INTO V_IDNO, V_NAME, V_CHECK, V_JOB, V_PAY;
中,您将其分配给 V_CHECK 这是数字
像这样更改顺序:FETCH paydata_cursor INTO V_IDNO, V_NAME, V_JOB, V_CHECK, V_PAY;
它应该可以工作,但要确保 paydata1.salary
是一个数字
我也不确定你什么时候声明了V_SAL
,那么你为什么在这个游标提取中使用V_CHECK
。
【讨论】:
【参考方案2】:在第 13 行,当您将光标 paydata_cursor 定义为类似列时
从 PAYDATA1 中选择 IDNO、姓名、工作代码、工资、PAYHR 按 IDNO 订购; 列序列 IDNO、NAME、JOBCODE、SALARY、PAYHR
但在第 23 行,即
FETCH paydata_cursor INTO V_IDNO, V_NAME, V_CHECK, V_JOB, V_PAY; 你实际上是在获取这样的列
IDNO, NAME, JOBCODE, SALARY, PAYHR 输入 V_IDNO、V_NAME、V_CHECK、V_JOB、V_PAY
这意味着 JOBCODE 正在进入 V_CHECK 并且 SALARY 将进入 V_JOB 因为salary 必须是数字并且v_check 必须是varchar
我认为这就是您收到此错误的原因
谢谢 席德
【讨论】:
【参考方案3】:我可以看到您的代码存在一些问题,但在不了解更多信息的情况下很难诊断...但我会尝试:
您在打开光标时似乎选择了错误的变量。
您还没有在任何地方打开您的paytran_cursor
。您可以自己添加该代码,但在您添加之前,您对 V_HOURSWK
的检查不会很有用等。
试试这个:
SET SERVEROUTPUT ON
DECLARE
V_IDNO PAYDATA1.IDNO%TYPE;
V_NAME PAYDATA1.NAME%TYPE;
V_SAL PAYDATA1.SALARY%TYPE;
V_JOB PAYDATA1.JOBCODE%TYPE;
V_PAY PAYDATA1.PAYHR%TYPE;
V_IDNO1 PAYTRAN1.IDNO%TYPE;
V_HOURSWK PAYTRAN1.HOURSWK%TYPE;
V_HOURS HOURSWKD.HOURSWK%TYPE;
V_CHECK NUMBER(10);
CURSOR paydata_cursor IS
SELECT IDNO, NAME, JOBCODE, SALARY, PAYHR
FROM PAYDATA1
ORDER BY IDNO;
CURSOR paytran_cursor IS
SELECT IDNO, HOURSWK
FROM PAYTRAN1
WHERE V_IDNO = IDNO
order by IDNO;
BEGIN
OPEN paydata_cursor;
LOOP
-- Changed the variables you were selecting into
FETCH paydata_cursor INTO V_IDNO, V_NAME, V_JOB, V_SAL, V_PAY;
EXIT WHEN paydata_cursor%NOTFOUND;
IF V_SAL > 0
THEN
V_CHECK := V_SAL / 52;
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
END IF;
IF V_SAL = 0 AND V_HOURSWK < 41
THEN
V_CHECK := V_PAY * V_HOURS;
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
ELSIF V_SAL = 0 AND V_HOURSWK > 40
THEN
V_CHECK := V_PAY * V_HOURS;
V_CHECK := V_SAL + ((V_HOURSWK * 1.5) * (V_HOURSWK - 40));
DBMS_OUTPUT.PUT_LINE(V_IDNO|| ' HAS A CHECK FOR: '||V_CHECK);
END IF;
END LOOP;
CLOSE paydata_cursor;
END;
/
SET SERVEROUTPUT OFF
希望对你有帮助。
编辑:
我试图猜测您要对代码执行什么操作,并认为以下内容可能会以某种更有效的方式解决您的问题:
SET SERVEROUTPUT ON
DECLARE
--
c_max_hours CONSTANT NUMBER := 40;
--
-- N.B.: I have assumed that there may be more than one entry per IDNO for
-- hours worked, if this is not the case then you can remove the SUM() and
-- the GROUP BY clause
--
CURSOR pay_cursor
IS
SELECT IDNO,
NAME,
JOBCODE,
SALARY,
PAYHR,
SUM(HOURSWK) AS HOURS_WORKED
FROM PAYDATA1
JOIN PAYTRAN1 USING (IDNO)
GROUP BY IDNO,
NAME,
JOBCODE,
SALARY,
PAYHR;
--
V_CHECK NUMBER;
pay_record pay_cursor%ROWTYPE;
--
BEGIN
-- Depending on the rows in your cursor you might want to increase the output buffer for DBMS_OUTPUT
DBMS_OUTPUT.ENABLE(1000000);
--
OPEN pay_cursor;
LOOP
-- Fetch the data into your cursor rowtype variable
FETCH paydata_cursor INTO pay_record;
EXIT WHEN pay_cursor%NOTFOUND;
--
-- ASSUMPTION: salary is not NULL (i.e. 0 or more).
--
IF pay_record.salary > 0
THEN
V_CHECK := pay_record.salary / 52;
ELSE
--
-- Salary must be zero
--
IF pay_record.hours_worked <= c_max_hours
THEN
V_CHECK := pay_record.payhr * pay_record.hours_worked;
ELSE
-- Must be > c_max_hours
V_CHECK := pay_record.payhr * pay_record.hours_worked;
V_CHECK := pay_record.salary + ((pay_record.hours_worked * 1.5) * (pay_record.hours_worked - 40));
END IF;
END IF;
--
-- Output your result
--
DBMS_OUTPUT.PUT_LINE(pay_record.idno|| ' HAS A CHECK FOR: '||V_CHECK);
END LOOP;
CLOSE paydata_cursor;
EXCEPTION
WHEN others
THEN
-- Close the cursor if it is still open
IF pay_cursor%ISOPEN
THEN
CLOSE pay_cursor;
END IF;
-- Re-raise the error
RAISE;
END;
/
SET SERVEROUTPUT OFF
我希望它有用。 附:我无法在真实环境中检查这一点,因为我不在我常用的 PC 上,因此对任何语法错误表示歉意。
【讨论】:
谢谢你们,你们太棒了,这解决了我的问题。 @FagnerSchundtCaetano,如果它解决了您的问题,您能否将答案标记为正确,因为它有助于反馈等。很高兴我能提供帮助。以上是关于错误 ORA-06502:PL/SQL:数字或值错误:字符到数字的转换错误 ORA-06512:在第 22 行的主要内容,如果未能解决你的问题,请参考以下文章
ORA-06502 PL/SQL:数字或值错误:字符到数字的转换错误;
ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误
ORA-06502: PL/SQL: 数字或值错误: NULL 索引表键值
ORA-06502: PL/SQL: 数字或值错误: 数字精度太大