Oracle - select one field into multiple variables - sql

I have a question that does not give me sleep.
How can I select one field and put in multiple variables in Oracle.
Example:
declare
v_num_1 number;
v_num_2 number;
v_num_3 number;
begin
select 123 into v_num_1, v_num_2, v_num_3
from dual;
end;
This code is obviously incorrect - I give an error about too many variables.
However, I wonder if it exist another way to put in one value into multiple variables?
I will be very grateful for help.

Just repeat the 123:
declare
v_num_1 number;
v_num_2 number;
v_num_3 number;
begin
select 123, 123, 123 into v_num_1, v_num_2, v_num_3
from dual;
end;
Or use simple assignment:
declare
v_num_1 number;
v_num_2 number;
v_num_3 number;
begin
v_num_1 := 123;
v_num_2 := 123;
v_num_3 := 123;
end;

Related

Getting the error: Procedure created with compilation errors.. What am I doing wrong? [duplicate]

I am trying to run the following query in SQL Developer, but I am receiving an error. I am trying to declare two local variables (var_num1 and payDate) and then set the variables. Does anyone know what I can be doing incorrectly? I know Oracle SQL is a little different than SQL Server.
DECLARE
var_num1 number;
payDate date;
BEGIN
var_num1 := 100;
payDate := '10/1/2013'
BEGIN
SELECT * FROM Paycode WHERE PaycodeID = var_num1 and PaycodeDate = payDate;
End;
END;
Error report:
ORA-06550: line 6, column 2:
PLS-00428: an INTO clause is expected in this SELECT statement
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
You cannot use SELECT without INTO clause in PL/SQL. The output of the SELECT must be stored somewhere. Eg. table or variable or perhaps a record. See example below how to store result of the SELECT statement into record.
DECLARE
var_num1 number;
payDate date;
v_result Paycode%ROWTYPE;
BEGIN
var_num1 := 100;
payDate := '10/1/2013';
SELECT * INTO v_result
FROM Paycode
WHERE PaycodeID = var_num1 and PaycodeDate = payDate;
END;
If you want to get a resultset back in SQL Developer with this code block you will need to open a ref cursor for the query e.g.
DECLARE
refCur REF CURSOR;
refc refCur;
var_num1 number;
payDate date;
v_result Paycode%ROWTYPE;
BEGIN
var_num1 := 100;
payDate := '10/1/2013';
OPEN refc FOR
SELECT *
FROM Paycode
WHERE PaycodeID = var_num1 and PaycodeDate = payDate;
END;

dbms_output.put_line write out each value from function

I've got a function that takes three number arguments and returns a value calculated from those three numbers. Now in another stored procedure I call try to write out each value like this:
CREATE OR REPLACE PROCEDURE P_POOL
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('test'||' '||POOL_PKG.F_REKTANGULÄR(6,4,2);
But I want to the output to be example:
test is 6 meter and 4 meter and 2 meter!
How can I add text after each value?
Try this
Package POOL_PKG
IS
FUNCTION F_REKTANGULÄR(meter_in NUMBER,height_in NUMBER,bottom_in NUMBER,Show_dims_in IN NUMBER := 0) RETURN NUMBER;
END POOL_PKG;
Package Body POOL_PKG is
FUNCTION F_REKTANGULÄR(meter_in NUMBER,height_in NUMBER,bottom_in NUMBER, Show_dims_in IN NUMBER := 0) RETURN NUMBER
v_result NUMBER(10);
v_unit VARCHAR2(10) := 'meter';
IS
--assert that all inputs are greater than 0
--and less than a reasonable amount
v_result := meter_in * height_in * bottom_in;
IF show_dims_in = 1
THEN
DBMS_OUTPUT(meter_in ||' '||v_unit||', '||height_in||' '||v_unit||', '||bottom_in);
END IF;
RETURN v_result;
END F_REKTANGULÄR;
END POOL_PKG;
and could be used this way
DECLARE
v_result NUMBER(9);
BEGIN
v_result := POOL_PKG.F_REKTANGULÄR(6 ,4 ,2,1);
END;
Or, given your comments this would work to:
Declare
a NUMBER(9);
b NUMBER(9);
c NUMBER(9);
v_unit VARCHAR2(10) := 'meter';
v_result NUMBER(9);
BEGIN
a := 6;
b := 4;
c := 2;
DBMS_OUTPUT(a||' '||v_unit||', '||b||' '||v_unit||', '||c||' '||v_unit);
v_result := POOL_PKG.F_REKTANGULÄR(a ,b ,c);
END;

Error in stored procedure execution in oracle

create procedure proc_insert_salary(salary_emp in NUMBER,
empid in NUMBER(10),
desig in varchar2(20))
begin
DECLARE
gr_sal,hr,da,pf number;
BEGIN
set hr:= salary_emp*(15/100);
set da:= salary_emp*(8/100);
set pf := salary_emp*(35/100);
set gr_sal := salary_emp+hr+da-pf;
insert into emp_salary_details values (empid,desig, salary_emp, gr_sal);
end;
call proc_insert_salary (45000,10100,'C.E.O.')
when I call this procedure it gives error its in invalid state.
While #Guneli's answer is adequate, there's really no reason for the second block in this case. The following would be equivalent (and slightly simpler).
CREATE OR REPLACE PROCEDURE proc_insert_salary (salary_emp IN NUMBER,
empid IN NUMBER,
desig IN VARCHAR2) AS
hr NUMBER := salary_emp * (15 / 100);
da NUMBER := salary_emp * (8 / 100);
pf NUMBER := salary_emp * (35 / 100);
gr_sal NUMBER := salary_emp + hr + da - pf;
BEGIN
INSERT INTO emp_salary_details
VALUES (empid,
desig,
salary_emp,
gr_sal);
END;
/
Also, you should not that if you're going to have any other SQL in the same script (such as the call) then you need to end the procedure definition with a slash (/). This tells Oracle that procedure is finished and that it should compile it. Really, it's a good practice to always include it after procedural code.
Well, try this instead:
CREATE OR REPLACE PROCEDURE proc_insert_salary(
salary_emp IN NUMBER,
empid IN NUMBER,
desig IN VARCHAR2)
AS
BEGIN
DECLARE
gr_sal NUMBER;
hr NUMBER;
da NUMBER;
pf NUMBER;
BEGIN
hr := salary_emp*(15/100);
da := salary_emp*(8/100);
pf := salary_emp*(35/100);
gr_sal := salary_emp+hr+da-pf;
INSERT INTO emp_salary_details VALUES (empid,desig, salary_emp, gr_sal);
END;
END;
The things to note are that:
1) You can not show the size for the parameters of subprograms in PL/SQL, so NUMBER(10) or VARCHAR2(20) are incorrect.
2)The one line declaration of variables is not supported in PL/SQL, so instead of gr_sal,hr,da,pf number; you should use
gr_sal NUMBER;
hr NUMBER;
da NUMBER;
pf NUMBER;
3)To assign a value to variable you should not use SET, the ':=' is enough.
4)Also you have missed the 'end' clause for your second 'begin'.

Pass multiple values to a single parameter in PL/SQL and insert them into a table

I want to pass a multiple values like '1,2,3,4,5,6,7,8,9,10,11,12' on as a single parameter and insert them into a table.
I have a scenario like saving a bill for particular customer, the customer might have purchased multiple items.
You can pass the values comma separated. This PL/SQL procedure breaks up a comma-separated string (passed as P_VALUE) and inserts each token into a table as a separate row, along with some other values.
PROCEDURE XXXXGL_INST_PARAMS (P_VALUE VARCHAR2) IS
i number;
n number;
r number;
pos number;
L_NAT_ACCT varchar2(10);
L_UID number;
BEGIN
L_UID := fnd_global.user_id;
n := length(P_VALUE);
i := 1;
r := 1;
WHILE (i < n) LOOP
pos := (INSTR(P_VALUE,',',1,r)-i);
IF pos < 0 THEN
pos := n;
END IF;
SELECT substr(P_VALUE,i,pos) INTO L_NAT_ACCT FROM dual;
INSERT INTO xxXXX.xxXXXgl_natural_accts_t
(NATURAL_ACCT, CREATION_DATE, CREATED_BY, LAST_UPDATE_LOGIN,
LAST_UPDATE_DATE, LAST_UPDATED_BY)
VALUES(L_NAT_ACCT,SYSDATE,L_UID,L_UID,SYSDATE,L_UID);
i := i + length(L_NAT_ACCT)+1;
r := r+1;
END LOOP;
END;
Note: I found this here.

plsql function must be declared

So I have this function called cal_approv that calculates a quantity of supply, by selecting
the sum of ordered quantity, the "present" quantity, and the min quantity of a giving product(idart)...fecthing information into cursor then inserting it into a result table(resultat), when i try to run this code
accept idarticle prompt 'Donner lid article : '
declare
FUNCTION cal_approv(code_art article.idart%type)
RETURN number IS qte _app number;
qtot number;
qtestk number;
qtemin number;
begin
select sum(qte_com) into qtot from lig_com where idart=code_art;
select qtestk into qtestk from article where idart=code_art;
select qtemin into qtemin from article where idart=code_art;
if ((qtot/qtestk)>(2*qtemin)) then
qte_app := qtot-qtestk*1.5;
else
qte_app := qtot*1.2;
end if;
return qte_app;
end;
/
drop function cal_approv;
declare
cursor arts is select idart, desart,pu from article where qtestk <= qtemin;
ida number;
da number;
qa number;
pa number;
begin
open arts;
loop
fetch arts into ida, da, pa;
qa := cal_ap prov(&idarticle);
pa := pa*cal_approv(&idarticle);
exit when(arts%notfound);
insert into resultat values(ida,da, qa,pa);
end loop;
close arts;
end;
/
select * from resultat;
I get this error
PLS-00201: identifier 'CAL_APPROV' must be declared
any help is appreciated!
Here's what I get when I indent your first block of PL/SQL code:
declare
FUNCTION cal_approv(code_art article.idart%type)
RETURN number
IS
qte_app number;
qtot number;
qtestk number;
qtemin number;
begin
select sum(qte_com) into qtot from lig_com where idart=code_art;
select qtestk into qtestk from article where idart=code_art;
select qtemin into qtemin from article where idart=code_art;
if ((qtot/qtestk)>(2*qtemin)) then
qte_app := qtot-qtestk*1.5;
else
qte_app := qtot*1.2;
end if;
return qte_app;
end;
/
Note that the end in the second-last line ends the function, not the anonymous PL/SQL block. This will cause an error because Oracle is expecting something like the following:
declare
FUNCTION cal_approv(code_art article.idart%type)
RETURN number
IS
-- ...
begin
-- body of function omitted
end;
begin
-- do something with this function
end;
/
Also, to be clear, a function declared within a PL/SQL block, rather than with a CREATE OR REPLACE FUNCTION ... statement, exists only while that block is being executed. Once the block completes, the function no longer exists. So you can write the following block:
DECLARE
FUNCTION add_one(p_in IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN p_in + 1;
END;
BEGIN
dbms_output.put_line(TO_CHAR(add_one(4));
END;
/
This should write 5 to dbms_output, if that has been enabled.
On the other hand, this won't work:
DECLARE
FUNCTION add_one(p_in IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN p_in + 1;
END;
BEGIN
NULL;
END;
/
BEGIN
dbms_output.put_line(TO_CHAR(add_one(4));
END;
/
This doesn't work because the function add_one is no longer available when the first block completes. The second block will fail with an error because it cannot find the function add_one.
There is no point attempting to use DROP FUNCTION with your function. DROP FUNCTION can only drop stored functions, and because your function is declared within a PL/SQL block, it is not a stored function.
As I see it you have two alternatives:
declare the function as a stored function, using CREATE OR REPLACE FUNCTION ..., outside of any DECLARE block, or
move all of the code that uses the function into the same block that declares the function.
In the latter case, your code would look something like the following (abbreviated for clarity):
declare
FUNCTION cal_approv(code_art article.idart%type)
RETURN number
IS
-- ...
begin
-- ...
end;
cursor arts is select idart, desart,pu from article where qtestk <= qtemin;
ida number;
da number;
qa number;
pa number;
begin
open arts;
loop
-- ...
end loop;
close arts;
end;
/