Oracle procedure insert from different sources - oracle

I can get what am I doing wrong here
create or replace procedure load_category(
p_linea_cod varchar2,
p_modal_cod varchar2,
p_periodo_cod varchar2
)IS
BEGIN
insert into category(categoryid,externalcategoryid,name)values(
SEQ_CATEGORY.nextval,
(select cod_modal_est,nombre
from modalidad_estud#ULINK
where cod_linea_negocio = p_linea_cod
and cod_modal_est = p_modal_cod)
);
END;
I'm trying to make a simple insert with a sequence and a select statement(working statement), but can get it work, just receiving this error:
ORA-00947: not enough values
I thank your help in advance.

Your select returns only one column, while you're inserting three. If you need to leave them empty, add NULL values to the select, or leave the columns out of the insert field list.
[edit]
Modified query:
insert into category(categoryid, externalcategoryid, name)
select
SEQ_CATEGORY.nextval, cod_modal_est, nombre
from
modalidad_estud#ULINK
where
cod_linea_negocio = p_linea_cod
and cod_modal_est = p_modal_cod;

Related

Error(13,61): PL/SQL: ORA-00984: column not allowed here IN PROCEDURE WHEN PASS IN PARAMETER

CREATE OR REPLACE PROCEDURE INSEMP
(
EMPNOS IN VARCHAR2
, ENAMES IN VARCHAR2
, JOBAS IN VARCHAR2
, MGRS IN VARCHAR2
, HIREDATES IN VARCHAR2
, SALS IN VARCHAR2
, COMMISSIONS IN VARCHAR2
, DEPTNOS IN VARCHAR2
) AS
BEGIN
INSERT INTO emp VALUES (EMPNOS,ENAMES,JOBAS,MGRS,HIREDATES,SALS,COMMS,DEPTNOS);
END INSEMP;
When I execute the above, I get an error: Error(13,67): PL/SQL: ORA-00984: column not allowed here.
I know when we insert
INSERT INTO EMP VALUES ('DSFD'DSFDFD', ...)
we have to use single quotes, but how do I pass the values in via the parameters?
Your issue is that you have a parameter called COMMISSIONS but in your insert statement, you are passing in a value of COMMS.
Also, make sure your parameters have different names to the columns you're trying to insert into; this is (IMO) good practice across any PL/SQL code you're writing, as you can have unexpected results when name collisions happen.
Change your insert statement to use the right parameter name (or, alternatively, change the name of the parameter to match your insert statement) and it should start working.
One point, though: it is bad practice to not list the columns you are inserting into. In real production code, if someone added a column to the table, your code would break.
Your insert statement would be better written as:
insert into <table> (<list of columns to be inserted into>)
values (<list of values to insert into those columns>);

SYS_REFCURSOR is returning all the rows from table without considering the IN parameter

I am facing a weird problem here.
PROCEDURE USL_EMPLOYEEBYID (
EMPLOYEE_ID IN NUMBER,
EMPIDCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN EMPIDCURSOR FOR
SELECT emp.employee_id,emp.employee_name,emp.present_address,emp.permanent_address,emp.status
FROM Employee_Info emp
WHERE emp.employee_id = EMPLOYEE_ID;
END;
This procedure should give me a single employee upon entering the employee Id. But it is returning all the employees.
What am I doing wrong here?
In your query, Oracle interprets EMPLOYEE_ID as the column EMPLOYEE_ID, not the input parameter, here you find something more; in this way, your where condition is something like a=a.
Change the parameter name to distinguish it from the table column:
PROCEDURE USL_EMPLOYEEBYID (
p_EMPLOYEE_ID IN NUMBER,
po_EMPIDCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN po_EMPIDCURSOR FOR
SELECT emp.employee_id,emp.employee_name,emp.present_address,emp.permanent_address,emp.status
FROM Employee_Info emp
WHERE emp.employee_id = p_EMPLOYEE_ID;
END;
this is a good practice, to always know in your code whether you are handling an input parameter, a local variable, a column and so on

pl sql insert into within a procedure and dynamic variables

I need some help with PL SQL. I have to insert some data into table. Another application is calling my procedure and caller is passing few details which I also need to insert into my table.
here is the syntax I am struggling with:
PROCEDURE invform_last2orders_item_insert( p_userId IN NUMBER
,p_accountId IN NUMBER
,p_site_Id IN NUMBER
,p_return_message OUT VARCHAR2) IS
Begin
insert into mytable
(p_userId , p_accountId , p_site_Id , sku, description, 'Cart', 1, unitId)
as
select sku, description, unitId
from mycatalogtable where site_id= p_site_Id ) ;
End;
Can you help me with syntax? I need to pass three parameters from called in parameter and some values returned from select query. How can I achieve this?
thank you for your help.
That would be something like this; see comments within code:
PROCEDURE invform_last2orders_item_insert
( p_userId IN NUMBER
,p_accountId IN NUMBER
,p_site_Id IN NUMBER
,p_return_message OUT VARCHAR2)
IS
Begin
insert into mytable
-- first name all columns you'll be inserting into; I don't know their
-- names so I just guessed
(userid,
accountid,
siteid,
sku,
description,
col1,
col2,
unitid
)
-- if you were to insert only values you got via parameters, you'd use the
-- VALUE keyword and insert those values separately.
-- As some of them belong to a table, use SELECT statement
(select p_userid,
p_accountid,
p_siteid,
c.sku,
c.description,
'Cart',
1,
c.unitid
from mycatalogtable c
where c.site_id = p_site_Id
);
-- I don't know what you are supposed to return; this is just an example
p_return_message := sql%rowcount || ' row(s) inserted';
End;
in your select statement you should have the same number of columns as you are inserting into the table, your code should be something like this example,
DECLARE
userid varchar2(20) := 'Jack';
Begin
INSERT INTO mytable (SELECT userid, SPORT from OLYM.OLYM_SPORTS);
commit;
end;

How to run Oracle function which returns more than one value

My test function is this
CREATE OR REPLACE FUNCTION MULTI_VAL
(MYNAME OUT EMP2017.ENAME%TYPE)
RETURN NUMBER AS
MYSAL EMP2017.SAL%TYPE;
BEGIN
SELECT SAL, ENAME INTO MYSAL, MYNAME FROM EMP2017 ;
RETURN MYSAL;
END;
/
When I run it like
variable mynm varchar2(20)
SELECT MULTI_VAL(:mynm) FROM dual;
it gives this error
ERROR at line 1:
ORA-06553: PLS-561: character set mismatch on value for parameter 'MYNAME'
The error you get now indicates a datatype mismatch.
However there is a fundamental problem with your code. We cannot use functions which have OUT parameters in SQL. So once you have fixed the datatype issue you will get this error: ORA-06572: Function MULTI_VAL has out arguments.
You can run it like this:
declare
n varchar2(20);
x number;
begin
x := multi_val(n);
end;
/
Generally, functions with OUT parameters are considered bad practice. The syntax allows them, but the usage is hard to understand. It's better to use a procedure with two OUT parameters (because we can only call the program in PL/SQL anyway) or else have the function return a user-defined type.
CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER);
INSERT INTO EMP2017 VALUES ('SMITH',5000);
INSERT INTO EMP2017 VALUES ('JOHNS',1000);
COMMIT;
CREATE TYPE RET_MULT AS OBJECT
(ENAME VARCHAR2(10),SAL NUMBER);
CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT;
CREATE OR REPLACE FUNCTION MULTI_VAL RETURN T_RET_MULT PIPELINED IS
MYSAL RET_MULT;
BEGIN
FOR I IN(SELECT SAL, ENAME FROM EMP2017) LOOP
MYSAL := RET_MULT(I.ENAME,I.SAL);
PIPE ROW(MYSAL);
END LOOP ;
RETURN ;
END;
SELECT * FROM TABLE(MULTI_VAL());
I think this question can be solved without using pipeline functions. Just like this. All pre required data as described #Sedat.Turan except function. Sorry for copy/past.
CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER);
INSERT INTO EMP2017 VALUES ('SMITH',5000);
INSERT INTO EMP2017 VALUES ('JOHNS',1000);
COMMIT;
CREATE TYPE RET_MULT AS OBJECT
(ENAME VARCHAR2(10),SAL NUMBER);
CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT;
create or replace function MULTI_VAL return T_RET_MULT is
RET_SET T_RET_MULT;
begin
select RET_MULT(ENAME, SAL) bulk collect into RET_SET from EMP2017;
return RET_SET;
end;

Pass column name and column value in a procedure that execute plsql query

In oracle PLSQL , how to pass a column name and column value to a procedure .
The procedure executes select command based on the where clause
such that Select * from FOO where columnname=columnnvalue
and the procedure stores the resultset (refcursor) in a OUT parameter.
here columnname and columnvalue are passed by user
As i can see you have not shared any inputs. I have tried to replicate
scenario as per your requirements. Please check below snippet. Hope it
helps
set serveroutput on;
CREATE OR REPLACE PROCEDURE USER_INPUT_PROC(
p_col_name_input IN VARCHAR2,
p_col_val_input IN VARCHAR2,
p_lst_out OUT sys_refcursor )
AS
lv_col VARCHAR2(10000 CHAR);
BEGIN
NULL;
SELECT DECODE(p_col_name_input,'empno',' AND EMPNO = '||''''||p_col_val_input||'''','ename',' AND ENAME = '||''''||p_col_val_input||'''','')
INTO lv_col
FROM DUAL;
OPEN p_lst_out FOR 'SELECT * FROM EMP
WHERE 1 = 1 '||lv_col;
END;
To do this safely you need to use the dbms_sql package. The coding becomes pretty involved.

Resources