I'm coding a DML package, and I would like create a simple procedure within package to updated commission_pct value. I don't receive any syntax error when I execute the package body but when I call the procedure I receive a unexpected error. Thanks.
PROCEDURE update_commission_pct(
p_empid employees.employee_id%TYPE,
p_new_comm employees.commission_pct%TYPE
)
IS
rec_confirm employees%ROWTYPE;
v_valid_empid BOOLEAN;
BEGIN
-- Simple boolean function to check employee existence
v_valid_empid := dml_employees_pkg.check_employee_id(p_empid);
IF
v_valid_empid = TRUE
AND LENGTH(p_new_comm) <=5 THEN
UPDATE employees
SET commission_pct = p_new_comm
WHERE employee_id = p_empid
RETURNING employee_id, commission_pct
INTO rec_confirm.employee_id, rec_confirm.commission_pct;
DBMS_OUTPUT.PUT_LINE('Comission updated successfully.');
DBMS_OUTPUT.PUT_LINE('Employee ID number ' ||
rec_confirm.employee_id || ' new comm is' ||
rec_confirm.commission_pct);
ELSE
RAISE_APPLICATION_ERROR(-20042, 'Employee ID ' ||
p_empid || ' Employee doesn't exist.');
END IF;
END update_commission_pct;
Call procedure in a simple PL/SQL block:
SET SERVEROUTPUT ON
BEGIN
dml_employees_pkg.update_commission_pct(550, 10);
END;
Oracle ERROR:
Informe de error -
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at "HR.DML_EMPLOYEES_PKG", line 118
ORA-06512: at line 2
01438. 00000 - "value larger than specified precision allowed for this column"
*Cause: When inserting or updating records, a numeric value was entered
that exceeded the precision defined for the column.
*Action: Enter a value that complies with the numeric column's precision,
or use the MODIFY option with the ALTER TABLE command to expand
the precision.
The commission_pct column in the employees table (in the default HR schema) is defined as number(2, 2).
The meaning of the precision and scale is explained inthe documentation, but essentially here it means the column can only accept values from 0.00 to 0.99. You're trying to insert 10, which - as the error says - exceeds the allowed precision.
If you want to store 10% you can either pass 0.1 as the second argument in your procedure call; or stick with passing 10 but then divide by 100 as part of the update statement:
SET commission_pct = p_new_comm/100
You may want to validate the passed value in some way other than checking its length. And at the moment if the LENGTH(p_new_comm) <=5 check fails, the raised exception doesn't make that clear - it only refers to the employee ID which may actually be valid. The length check doesn't really sense anyway though.
Related
so I made a trigger insert like this:
create or replace trigger discount
after insert on transaction
for each row
begin
if (new.desc_date = 'Y') then
insert into desc_transaction(discount) values (new.discount = '0.1');
end if;
end;
/
Warning: Trigger created with compilation errors.
show error;
3/1 PL/SQL: SQL Statement ignored
3/54 PL/SQL: ORA-00917: missing comma
how to solve it.
data :
desc_date contains only yes and no because if November is discounted and October is not.
For the discount section contains 0.1 and null so if desc_date is yes then 0.1 otherwise it will be null or ' '.
Wrong syntax. Should've been
CREATE OR REPLACE TRIGGER discount
AFTER INSERT
ON transaction
FOR EACH ROW
BEGIN
IF :new.desc_date = 'Y'
THEN
INSERT INTO desc_transaction (discount)
VALUES (0.1);
END IF;
END;
/
Or, possibly even better,
CREATE OR REPLACE TRIGGER discount
AFTER INSERT
ON transaction
FOR EACH ROW
BEGIN
INSERT INTO desc_transaction (discount)
VALUES (CASE WHEN :new.desc_date = 'Y' THEN 0.1 ELSE NULL END);
END;
/
The syntax of your insert statement is incorrect. Try the following:
insert into desc_transaction(discount) values ('0.1');
Side note - discount probably isn't a varchar column. If this guess is correct, you should be using a numeral literal (0.1) and not a string literal ('0.1') like you currently have.
I want to solve this:
Create a stored procedure named insert_num_proc that will insert numbers into the FLOAT_SAMPLE table.
This procedure should have two parameters, one for each of the two columns in this table.
The procedure should check the float_id column to ensure there is no duplicate (as unique values are not enforced in this column). If
there is a duplicate float_id, then the row should not be inserted,
instead printing a message saying “Duplicate value in float_id”.
Below is my query. For the second query, I execute my stored procedure to see if it shows my application error message, and it is not working.
CREATE OR REPLACE PROCEDURE insert_num_proc
(
float_id_param float_sample.float_id%TYPE,
float_value_param float_sample.float_value%TYPE)
AS
float_checker float_sample.float_id%TYPE;
BEGIN
SELECT float_id INTO float_checker FROM float_sample;
INSERT INTO float_sample (float_id, float_value)
VALUES
(float_id_param, float_value_param);
IF float_checker = float_id_param THEN
RAISE_APPLICATION_ERROR(-20001, 'Duplicate value is inserted.');
END IF;
END;
/
EXECUTE insert_num_proc(3,2);
Below is error message I get
Error report - ORA-01422: exact fetch returns more than requested
number of rows ORA-06512: at "DL29232.INSERT_NUM_PROC", line 9
ORA-06512: at line 1
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
You are missing a WHERE clause to check if that id exists, so it returns multiple rows which the single static variable float_checker cannot hold.
Another problem is that if you don't have an entry already in the table, your select statement will fail with no_data_found exception.
So, define your float_checker differently so that it will save the count.
Further, your INSERT should come after the IF condition
CREATE OR REPLACE PROCEDURE insert_num_proc (
float_id_param float_sample.float_id%TYPE,
float_value_param float_sample.float_value%TYPE
) AS
float_checker INTEGER := 0;
BEGIN
SELECT COUNT(*)
INTO float_checker
FROM float_sample WHERE
float_id = float_id_param; --where clause for the passed id.
IF float_checker > 0
THEN
raise_application_error(-20001,'Duplicate value is inserted.');
END IF;
INSERT INTO float_sample (
float_id,
float_value
) VALUES (
float_id_param,
float_value_param
);
END;
/
Since this is an exercise, it's ok to use this code. But, in a real time scenario, the 3rd requirement should be handled by a UNIQUE CONSTRAINT on the table.
I'm trying to figure out a simple ORACLE PL/SQL programming problem and I'm having some difficulties with it.
I have to make a trigger that catches inserts into a table, and if the location attribute of the new tuple getting into that table doesn't exist in the database, I need to throw a warning message and insert that new location into another table.
What I have now so far -
CREATE TRIGGER sightTrigger
AFTER INSERT ON SIGHTINGS
FOR EACH ROW
DECLARE
ct INTEGER;
BEGIN
SELECT COUNT(*)
INTO ct
FROM SIGHTINGS
WHERE SIGHTINGS.location <> :NEW.location;
IF ct > 0 THEN
RAISE_APPLICATION_ERROR('WARNING SIGN' || :NEW.location ||' does not exist in the database');
INSERT INTO FEATURES(LOCATION, CLASS, LATITUDE, ...)
VALUES (:NEW.LOCATION, 'UNKNOWN', ...);
END IF;
END;
I'm getting an error, "PLS-00306: wrong number of types of arguments in call to 'RAISE_APP_ERROR'. Could somebody tell me what's wrong? thank you
Try this:
RAISE_APPLICATION_ERROR(
-20001,
'WARNING SIGN' || :NEW.location || 'does not exist in the database'
);
Your RAISE_APPLICATION_ERROR takes two arguments (this is from Oracle docs): where error_number is a negative integer in the range -20000 .. -20999 and message is a character string up to 2048 bytes long.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
View Exhibit 1 and examine the structure of the employees table :
desc employees
Name Null Type
-------------------------------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL CHAR(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
View Exhibit 2 and examine the code:
CREATE OR REPLACE FUNCTION increase
(emp_num NUMBER) RETURN NUMBER
IS
inc_amt NUMBER;
sal NUMBER;
BEGIN
SELECT salary INTO sal FROM employees WHERE employee_id = emp_num;
inc_amt := sal*10;
RETURN inc_amt;
END increase;
/
CREATE OR REPLACE PROCEDURE calc_sal IS
emp_num NUMBER(7) := 120;
amt NUMBER :=0;
PROCEDURE raise_salary
(emp_id NUMBER)
IS
BEGIN
amt := increase(emp_num);
UPDATE employees SET salary = salary+amt WHERE employee_id=emp_id;
END raise_salary;
BEGIN
raise_salary(emp_num);
END calc_sal;
/
What is the outcome when the code is executed?
A.Both blocks compile and execute successfully when called.
B.Both blocks compile successfully but the CALC_SAL procedure gives an error on execution.
C.The CALC_SAL procedure gives an error on compilation because the amt variable should be declared in the RAISE_SALARY procedure.
D.The CALC_SAL procedure gives an error on compilation because the RAISE_SALARY procedure cannot call the stand-alone increase function.
I chose B because i compiled function and procedure and its compile sucssfully but I've tried to invoke(execute) procedure calc_sal and its give me error.
can you Explain to me what's the reason for this error and is my answer correct or false? because in dumps the answer was A
i invoke the procedure with this code :
begin
calc_sal;
end;
and the error i get :
Error report:
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at "HR.CALC_SAL", line 7
ORA-06512: at "HR.CALC_SAL", line 11
ORA-06512: at line 2
01438. 00000 - "value larger than specified precision allowed for this column"
*Cause: When inserting or updating records, a numeric value was entered
that exceeded the precision defined for the column.
*Action: Enter a value that complies with the numeric column's precision,
or use the MODIFY option with the ALTER TABLE command to expand
the precision.
and employee_id column there is 107 employee Their numbers from 100 to 206.
As Bob's comments state correctly, the code does work correctly, so the quiz answer A is defensible.
You're saying B because you get this error:
ORA-01438: value larger than specified precision allowed for this
column
This is a data problem. The function CALC_SAL() will succeed providing SAL + SAL*10 is <= 999999.99, the maximum value which will fit into a column defined as NUMBER(8,2). So either your table is not defined the way you think it is, or the employee's original salary ishigher then you think it is.
SET SERVEROUTPUT ON
VARIABLE dept_id NUMBER
DECLARE
max_deptno NUMBER(3);
dept_name departments.department_name%TYPE :='Education';
BEGIN
SELECT MAX(department_id)
INTO max_deptno
FROM departments;
DBMS_OUTPUT.PUT_LINE ('The maximum department no is : ' || max_deptno);
:dept_id:=(max_deptno+10);
INSERT INTO departments (department_name, department_id,location_id)
VALUES(dept_name, :dept_id, NULL);
DBMS_OUTPUT.PUT_LINE ('The number of rows affected : ' || SQL%ROWCOUNT);
END;
/
Error report:
ORA-01400: cannot insert NULL into ("SYSTEM"."DEPARTMENTS"."DEPARTMENT_ID")
ORA-06512: at line 10
01400. 00000 - "cannot insert NULL into (%s)"
*Cause:
*Action:
The maximum department no is : 190
I am getting this error while trying to execute the bind variable in oracle statment. But if i put some value instead of bind variable, i get this insert statement right. What am I doing wrong here?
I think the value of the bind variable is only set when the pl/sql block is finished. And it probably has to terminate normally.
One solution is to use max_deptno+10 in the insert insead of :dept_if. A better solution is to create another pl/sql variable and use that in the insert statement.
new_dept_id := max_deptno+10;
:dept_id := new_dept_id;
You also have to change the INSERT statement:
INSERT INTO departments (department_name,department_id,location_id)
VALUES(dept_name, new_dept_id, NULL);
I think this error is obtained because you use bind variable without using set autoprint on in start program.