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

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>);

Related

PLS-00103: Encountered Symbol DECLARE/EOF when trying to increment values with a sequence

I'm working on a procedure that will declare a variable, take the value from a procedure that increments, and inserts that value along with other parameters into a table. I thought I had it all worked out, but then I got hit with PLS-00103: Encountered symbol "DECLARE" and Encountered symbol "end-of-file". I feel like I'm so close, so any help would be majorly appreciated! Thank you!
create or replace procedure Order_Create(date_order string, cust_id char, total float, employ_id number)
is
DECLARE NewKey;
BEGIN
NewKey := order_auto_inc.nextval;
UPDATE Progressive_Keys set Order_Limit = NewKey;
insert into ORDERS VALUES (Progressive_Keys.Order_Limit, to_date(date_order, 'yyyy-mm-dd'), cust_id, total, employ_id);
commit;
END;
Remove the declare it's not needed in a stored procedures (as documented in the manual).
A variable declaration needs a data type.
As the parameter order_date is supposed to be a date, it should be declared with that type.
You can't access the column order_limit outside of a statement that uses the table progressive_keys so you need to use the variable in the insert statement as well.
It's also good coding practice to always list the target columns in an INSERT statement (note that I just invented some column names for the orders table you will have to adjust them to reflect the real names in your table)
create or replace procedure Order_Create(date_order date, cust_id varchar, total float, employ_id number)
is
NewKey number;
BEGIN
NewKey := order_auto_inc.nextval;
UPDATE Progressive_Keys set Order_Limit = NewKey;
insert into ORDERS (some_key, order_date, customer_id, total, employee_id)
VALUES (newkey, date_order, cust_id, total, employ_id);
commit;
END;
The UPDATE looks a bit strange as it will update all rows in the thable progressive_keys not just one row.

VARCHAR Leading 0's are lost when executing PLSQL procedures

I have a PL/SQL script which executes a number of procedures on an oracle DB.
The script defines:
DECLARE
productkey VARCHAR2(100);
BEGIN
productKey := '000000000070307037';
...
ProcedureName(productKey);
The procedure expects a VARCHAR2
PROCEDURE ProcedureName (
productKey VARCHAR2
)
The procedure inserts into a table:
BEGIN
Insert into Mytable
(
THIS_PRODUCT_KEY
)
Values
(productKey);
When I query that table, the product Key = 70307037, ie the leading 0's have been lost.
I saw some similar questions where TO_CHAR was suggested, I tried defining productKey in the script using TO_CHAR, and also modifiying the procedure to write using TO_CHAR:
BEGIN
Insert into Mytable
(
THIS_PRODUCT_KEY
)
Values
(TO_CHAR(productKey,'000000000000000000'));
Still coming through without the leading 0's.
There are multiple queries that join using the product key and don't work when the 0's are missing.
Why would I lose the 0's when the variable is a VARCHAR ?
I believe that "THIS_PRODUCT_KEY" column in your "Mytable" table is not a varchar2 column. I think it is number. If you change the datatype of the "THIS_PRODUCT_KEY" column to varchar2, it won't lose the 0s.

concatenate multiple clobs withing Oracle Procedure

I have an Oracle procedure that is going to accept multiple values within a parameter. Part of the procedure will run a select statement putting the results of the parameter in the where clause and placing the concatenated CLOBs into a variable. I am currently using the query below in the procedure but when I run it I get the error below.
If CLOB_ID is not null then
SELECT cast((collect(CLOB_TEXT) )as CLOB )
into v_MessageBody
FROM MESSAGE_CLOB_TABLE
WHERE MESSAGE_ID in CLOB_ID;
End If;
Error: ORA-00932: incosistant datatypes: expected - got CLOB
I also tried writing this using a LISTAGG function but LISTAGG doesnt work with the CLOB values in the MESSAGE_CLOB_TABLE
Any help would be greatly appreciated! I am using Oracle 11g.
If you need to concatenate in PL/SQL simplest variant is to loop through all selected records and append all found records to result:
create or replace function get_message(p_msg_id in number) return CLOB
is
v_MessageBody CLOB;
begin
-- create new instance of temporary CLOB
dbms_lob.createtemporary(v_MessageBody, true);
-- Fill instance with lines
for cMessages in (
select clob_text
from message_clob_table
where message_id = p_msg_id
order by message_row
)
loop
-- add line
dbms_lob.append(v_MessageBody, cMessages.clob_text);
end loop;
-- return collected lines as single CLOB
return v_MessageBody;
end;
Example above works if type of CLOB_TEXT field is CLOB and you need to collect only one message. You can test function in this SQLFiddle.
If you need to select many messages together based on list of his ID's, function becomes a little bit more complex, but principle remains the same.

table column containing list of other table column

create table cdi(comp_id varchar2(3),pk_key varchar2(2000));
insert into cdi values('abc','empno,ename,job');
insert into cdi values('pqr','empno,job,mgr');
insert into cdi values('cde','empno,mgr,sal');
commit;
create table emp_test(empno integer,ename varchar2(200),job varchar2(200),mrg integer,sal integer);
insert into emp_test values(1,'Gaurav Soni','DB',12,12000);
insert into emp_test values(2,'Niharika Saraf','Law',13,12000);
insert into emp_test values(2,'Niharika Saraf','Law',13,12000);
insert into emp_test values(3,'Saurabh Soni',null,12,12000);
commit;
In cdi table comp_id is primary key
create or replace procedure test(p_comp_id IN cdi.comp_id%TYPE
,p_empno IN emp_test.empno%TYPE
)
IS
TYPE ref_cur is ref cursor;
v_cur ref_cur;
v_pk_key cdi.pk_key%TYPE;
BEGIN
OPEN v_cur is select pk_key from cdi where comp_id =p_comp_id;
fetch v_cur into v_pk_key;
--now this list v_pk_key is primary key for that comp_id
--so following things need to be done
--1.check the emp_test table with this column list (v_pk_key )
--2. whether for that emp_no the primary key is null eg.
-- incase of comp_id cde ...empno,mgr,sal value should be not null
--if any of the value is null raise an error
--3.If there are two rows for that primary also raise an error.
-- for eg comp_id=abc two rows are fetched from emp_test
close v_cur;
END;
I am not sure of the approach what should i do to,first i think of concatenating the v_pk_key like empno||ename||job and then used this in select query ,but not able to check for null values ,i am confused what to do .
EDIT
what i have tried was to convert the list v_pk_key to
NVL(empno,'$')||NVL(ename,'$')||NVL(job,'$') and then
select v_pk_list from emp_test where empno=p_empno;
and then check for $ in the result if there is no $ in the result i ll check for more than one row,but i am not finding this as an efficient solution
if anyone give me a jist of it ,i will solve this .
I would split out that list of values, which really represents 3 columns ('empno, ename, job'). Use instr function, or create a separate function to split and return a pl/sql table, but either way it would be much more clear what is intended in the code.
See here for a SO link to some examples using instr to split csv fields.
Once you have 3 separate local variables with these values (l_empno, l_ename, l_job), then you can use much easier in your various SQL statements (where l_empno = blah and l_ename not in (blahblah)), etc...

Oracle procedure insert from different sources

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;

Resources