Insert value with substitution variable - sql

How can i use substitution variable in loop for inserting value in the below statement... loop limit is 5 times :
insert into emp
(eid, ename, salary, hire_date, address)
values
(&eid, '&ename', &salary, '&hire_date', '&address');

Related

'Column not allowed' error when adding data from cursor to table in pl/sql

I'm working on some practice problems to help me learn pl/sql. I'm required to use a cursor to add data from one table to another. My code is below. I've used dbms_output.put_line to make sure there is data in the cursor and the data in the cursor is making it into the variables c_ename and c_salary one row at a time through the loop. The problem seems to be that the data in the variables cannot be inserted into the top_paid_emp table. I'm getting a ORA-00984: column not allowed here error. I'm thinking it's a syntax error, but I don't understand where. Any help much appreciated.
DECLARE
c_ename VARCHAR2(20);
c_salary NUMBER(10);
CURSOR c_topfive IS
SELECT ename, salary
FROM (SELECT ename, salary,
RANK() OVER (ORDER BY salary DESC) AS rank
FROM emp1)
WHERE rank <= 5;
BEGIN
OPEN c_topfive;
LOOP
FETCH c_topfive INTO c_ename, c_salary;
dbms_output.put_line(c_ename);
EXIT WHEN c_topfive%notfound;
INSERT INTO top_paid_emp (empname, salary) VALUES (c_name,c_salary);
END LOOP;
CLOSE c_topfive;
END;
If you're fetching
FETCH c_topfive INTO c_ename, c_salary;
-------
then you should have used it in insert as well
INSERT INTO top_paid_emp (empname, salary) VALUES (c_name,c_salary);
------
Note that you could've done it using a cursor FOR loop, such as
begin
for cur_r in (select ename, salary
from (select ename, salary,
rank() over (order by salary desc) as rank
from emp1)
where rank <= 5)
loop
insert into top_paid_emp (empname, salary) values (cur_r.ename, cur_r.salary);
end loop;
end;
As you can see, it saves you from quite a lot of work: you don't have to declare any cursor variables, open the cursor, fetch, pay attention when to exit the loop, close the cursor - Oracle does all of it for you.

SQL get user input and further use it

I've got this task of inserting a new record into table EMPLOYEES. I know how to do it by asking the user to type in a value, for instance:
INSERT INTO EMPLOYEES (first_name, last_name, email, hire_date, job_id)
VALUES ('&first_name', '&last_name', '&email' ,'&hire_date', 'SA_REP' );
However, I'd like not to ask the user about the email but rather insert it automatically by taking the first letter of the first_name input concatenated with the last_name of the person whose data is being added to the table. In order to do this, I think I have to store the inserted values temporarily or at least get some reference to the first_name and last_name. I tried searching online but really got nowhere. Could you provide me with the simplest solution to this task? I'm using Oracle SQL Developer.
You may wrap it inside a PL/SQL block to use appropriate variables with right datatypes. This will also ensure that values for date variable is entered correctly, in the right format expected.
DECLARE
v_first_name employees.first_name%type := '&first_name';
v_last_name employees.last_name%type := '&last_name';
v_hire_date employees.hire_date%type := TO_DATE('&hire_date_YYYYMMDD','YYYYMMDD');
BEGIN
INSERT INTO EMPLOYEES (first_name, last_name, email, hire_date, job_id)
VALUES (v_first_name, v_last_name,
substr(v_first_name,1,1)||'.'||v_last_name , v_hire_date, 'SA_REP' );
--first letter of the first_name with last name
END;
/
Result
Enter value for first_name: John
Enter value for last_name: Doe
Enter value for hire_date_YYYYMMDD: 20190521
..
..
PL/SQL procedure successfully completed.
You should be able to do this:
INSERT INTO EMPLOYEES (first_name, last_name, email, hire_date, job_id)
VALUES ('&first_name', '&last_name', '&first_name' || '.' || '&last_name' ,'&hire_date', 'SA_REP' );

In PL SQL I want to refactor this for loop with inserts, by using BULK COLLECT and FORALL

For performance reasons, I want to rewrite the following to use BULK COLLECT and FORALL, rather than doing the inserts in a loop. The problem I'm running in to, is that empID must be generated on each iteration of the loop, or I need to do something similar with BULK COLLECT to create a collection to use FORALL on.
...
FOR i in 1 .. numberOfEmployeesToAdd
LOOP
BEGIN
empID := EMPLOYEE_SEQ.NEXTVAL;
INSERT INTO EMPLOYEE (ID,FIRST_NAME,LAST_NAME)
VALUES (empID, 'firstNameTest', 'lastNameTest');
INSERT INTO EMPLOYEE_DEPT_ASSOC (ID, DEPT_ID, EMP_ID)
VALUES (EMPLOYEE_DEPT_ASSOC_SEQ.NEXTVAL, '247', empID);
INSERT INTO SKILLSET (ID, EMP_ID, SKILL_ID)
VALUES (SKILLSET_ASSOC.NEXTVAL, empID, '702');
END;
END LOOP;
The examples of BULK COLLECT and FORALL seem to mostly consist of creating a cursor where you do select * from [some table] and then fetch that cursor and do a BULK COLLECT. But, I need to somehow dynamically assign values within a cursor using the next contiguous 'numberOfEmployeesToAdd' number of IDs and then do a FORALL to do the inserts.
Wont this help you? If you have a nested table with your set of data, you can join it to the SELECT
INSERT INTO EMPLOYEE (ID,FIRST_NAME,LAST_NAME)
SELECT EMPLOYEE_SEQ.NEXTVAL, 'firstNameTest', 'lastNameTest'
FROM DUAL
CONNECT BY LEVEL <= numberOfEmployeesToAdd;
INSERT INTO EMPLOYEE_DEPT_ASSOC (ID, DEPT_ID, EMP_ID)
SELECT EMPLOYEE_DEPT_ASSOC_SEQ.NEXTVAL, '247', ID
FROM EMPLOYEE;
INSERT INTO SKILLSET (ID, EMP_ID, SKILL_ID)
SELECT SKILLSET_ASSOC.NEXTVAL, ID, '702'
FROM EMPLOYEE;

ORA-00984 column not allowed here

I am getting error
"Execute-984 ORA-00984: column not allowed here"
while I am inserting values in my table Registred_Customer using Pro*C
Registred_Customer is defined as
CREATE TABLE Registred_Customer (
Cust_id NUMBER(6) PRIMARY KEY,
Name VARCHAR2(20) NOT NULL,
Age NUMBER,
Sex CHAR,
Addr VARCHAR2(50),
Contact NUMBER(10)
);
Inserting values using a pro*c method
addCustomer(i, name,age, gender, address,contectNo);
in Pro*C method I use following code to insert
EXEC SQL INSERT INTO REGISTRED_CUSTOMER VALUES
(cust_id, cust_name, age, sex, addr, contact);
here cust_name and addr are char *; and sex is char rest as int;
It reports error while using variable but works fine using direct values
like EXEC SQL INSERT INTO REGISTRED_CUSTOMER VALUES (10, 'Pankaj', 23, 'M', 'asdfs', 45875);
I tried changing few lines but in vain.
Thanks in advance.
Your Pro*C code is basically missing the colons (assuming that your formal parameters are called cust_id, cust_name, age etc.):
EXEC SQL INSERT INTO REGISTRED_CUSTOMER VALUES
(:cust_id, :cust_name, :age, :sex, :addr, :contact);
And it would be more robust to explicitly specify the columns name. Otherwise a change to the table schema can result in difficult to find bugs:
EXEC SQL INSERT INTO REGISTRED_CUSTOMER (Cust_Id, Name, Ag, Sex, Addr, Contact)
VALUES (:cust_id, :cust_name, :age, :sex, :addr, :contact);
If im seeing correct you are trying to insert into the columns, the columns??
"EXEC SQL INSERT INTO REGISTRED_CUSTOMER VALUES (cust_id, cust_name, age, sex, addr, contact);"??
it would be more helpful if you post your procedure complete.
Regards
As Mr. mentioned, you are trying to use the columns as input values. When you provide actual values it works. Are you perhaps meaning to use PL/SQL variables or the procedure arguments? In this case, whatever your procedure parameters are called is what you should put in the values section.
i.e if addCustomer looks like
PROCEDURE addCustomer (pId NUMBER, pName VARCHAR2, pAge NUMBER, pGender CHAR, pAddress VARCHAR2, pContact NUMBER)
Then you'd do something like
INSERT INTO registered_customer (cust_id, name, age, sex, addr, contact) VALUES (pId, pName, pAge, pGender, pAddress, pContact);
But if you are inserting into all columns you can leave out the column definition and just provide values
I also got this error message in a stored procedure doing an insert. I misspelled a parameter name in the values clause and the oracle interpreter saw the misspelled name as a column name and issued the 00984.

insert statement in oracle without using user defined function

I have table employees with columns eno, ename, job, sal, comm
and the query like
INSERT a new employee
eno as 7787,
ename as 'abc',
job as 'salesman'
sal as 2000,
comm as tax amount
this tax is the function like
CREATE OR REPLACE FUNCTION tax
( p_sal employees.sal%type
)
RETURN NUMBER
IS
v_tax employees.sal%type;
BEGIN
v_tax:= CASE
WHEN SAL> 4000 THEN SAL * 0.33
WHEN SAL >2500 THEN SAL *0.25
WHEN SAL >1500 THEN SAL * 0.20
ELSE 0
END;
RETURN v_tax
END tax;
At the INSERT statement I can't use function tax for the column comm.
Is there any other method to do this, or how can this be best achieved?
When you say
I can't use function tax for the column comm
do you mean you're not allowed to use this function, or you can't figure out how to use it?
Assuming the latter, I don't see why you shouldn't be able to use a function in an INSERT statement. You have, however, got the syntax of the INSERT statement completely wrong.
Try
INSERT INTO employee (eno, ename, job, sal, comm)
VALUES (7787, 'abc', 'salesman', 2000, tax(2000));
I don't know where amount in your INSERT statement comes from, but given that your function takes a parameter called p_sal, I'm guessing it's applied to the value in the column sal.