我试着解决这个问题两天而且我无法解决
我知道为什么代码会发生但我不知道在哪里。
或者为什么会发生......
这必须在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
答案 0 :(得分:0)
问题是您的专栏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
。
答案 1 :(得分:0)
我可以看到您的代码存在一些问题但却不知道更多信息很难诊断......但我会尝试:
打开光标时,您似乎正在选择错误的变量。
您还无法在任何地方打开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上,因此对任何语法错误表示道歉。
答案 2 :(得分:0)
从PAYDATA1中选择IDNO,NAME,JOBCODE,SALARY,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
因为薪水必须是数字,而v_check必须是varchar
我认为这就是你收到此错误的原因
由于 SID