plsql for inserting a table - oracle

declare
dno number(4);
dname varchar2(5);
ddate date;
dbasic number(10);
djob varchar2(15);
dcomm number(5);
dept number(5);
dmgr number(5);
begin
select empno,ename,hiredate,sal,job1,comm,deptno,mgr
into dno,dname,ddate,dbasic,djob,dcomm,dept,dmgr
from emp
where empno=&userno;
if sql%rowcount>0
then
insert into newempl
values(dno,dname,djob,dmgr,ddate,dbasic,dcomm,dept);
dbms_output.put_line('records inserted into it');
dbms_output.put_line(dno||' '||dname||' '||ddate||' '||dbasic);
end if;
end;
Error report:
ORA-01858: a non-numeric character was found where a numeric was expected
ORA-06512: at line 19
01858. 00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
I do not understand what the error is.

From the error message it looks like you're inserting values into the wrong columns. Without seeing your table structure (from describe newmpl for example) this is a bit of a guess, but this statement:
insert into newempl
values(dno,dname,djob,dmgr,ddate,dbasic,dcomm,dept);
... is assuming that the columns in the newempl table are in a certain order, which may not be (and appears to not be) the case. More specifically here, I think it's complaining about hiredate, as you're implicitly putting the djob value in that column - assuming the new table looks like emp - and the djob value can't be converted into a date.
Update based on comment: from how you said you created the table, this is equivalent to:
insert into newempl(dno, dname, ddate, dbasic, djob, dcomm, dept, dmgr)
values(dno,dname,djob,dmgr,ddate,dbasic,dcomm,dept);
... so as you can see when it's laid out like that the columns are not aligned, and you are indeed trying to put your djob value into the ddate column, which won't work.
It is always safer to explicitly specify the columns, both to prevent problems with different ordering in different environments (though that shouldn't really happen with controlled code) and to prevent this breaking if a new column is added. Something like:
insert into newempl(empno,ename,jon1,mgr,hiredate,sal,comm,deptno)
values(dno,dname,djob,dmgr,ddate,dbasic,dcomm,dept);
As an aside, when declaring your local variables you could specify them based on the table, for example dno emp.empno%TYPE. And as another aside based on your comment, I'd recommend giving local variables different names to the table columns to avoid confusion.
As a_horse_with_no_name said, this can be done with a simple SQL insert, and even within a PL/SQL block it doesn't need separate select and insert statements; you could just do:
insert into newempl(empno,ename,jon1,mgr,hiredate,sal,comm,deptno)
select empno,ename,jon1,mgr,hiredate,sal,comm,deptno
from emp
where empno=&userno;
Unfortunately none of this addresses the requirement that 'the employees who are managers must be inserted into new table', since you aren't doing anything with the mgr column. I don't think it would be constructive to do that part of the task for you at this point though, and I'm not sure where &userno fits in to that.

Related

PL/SQL Bind Variable in an Insert Statement ,

VARIABLE dept_id NUMBER
SET AUTOPRINT ON
DECLARE
max_dept departments.department_id%TYPE;
dept_name departments.department_name%TYPE := 'Revenue';
BEGIN
SELECT MAX(department_id)
INTO max_dept
FROM departments;
:dept_id := max_dept +10;
INSERT INTO departments (department_id,department_name,location_id)
VALUES(:dept_id,dept_name,NULL);
END;
Returns error
Error report: ORA-01400: cannot insert NULL into
("HR"."DEPARTMENTS"."DEPARTMENT_ID") ORA-06512: at line 13
01400. 00000 - "cannot insert NULL into (%s)"
*Cause:
I'm going to suggest something quite different here. That approach is doomed to failure once your application gets out "in the wild".
Let's say your application is a huge success and now you have dozens of people all using it at the same time, and lets assume currently 1000 is the highest department number.
Now we have 20 people all at roughly the same time doing:
SELECT MAX(department_id)
INTO max_dept
FROM departments;
They will all get 1000 as a result, and they will all then try insert 1010 into the table. One of two things will then happen
a) all except of one them will get an error due a primary key violation,
b) you have will multiple rows all with dept=1010
Either of these obviously is not great. This is why we have a thing called a sequence that can guarantee to give you unique values. You just do:
create sequence DEPT_SEQ;
and then do your inserts:
INSERT INTO departments (department_id,department_name,location_id)
VALUES(dept_seq.nextval,dept_name,NULL);
There are even easier mechanisms (google for "oracle identity column") but this heopfully explains the way forward and will save you from the problems with your current approach.

how to insert in oracle 10g database and returns the ID generated using stored procedure

I am very new to oracle's sql developer (since we've studied mysql) as well as in programming. I've searched in this website the answer to my question but I really can't understand the solutions provided.
What I want is to return the ID generated after inserting an object from java into the database. I'm using mybatis and oracle 10g database. I've already created the table and its columns.
Here's my code for the mapper
<insert id="addUser" parameterType="User" statementType="CALLABLE">
{ CALL addUserSP(
#{user.surname, javaType=String, jdbcType=VARCHAR, mode=IN},
#{user.firstName, javaType=String, jdbcType=VARCHAR, mode=IN},
#{userId, javaType=Integer, jdbcType=NUMBER, mode=OUT}
)}
</insert>
Here's my stored procedure (and I've already create a package named 'CREATEUSER')
PROCEDURE ADDUSERSP
( surname IN VARCHAR2,
firstName IN VARCHAR2,
userId OUT NUMBER
) AS
BEGIN
INSERT INTO users("surname", "first_name")
VALUES (surname, firstName);
RETURNING user_id INTO userId;
END ADDUSERSP;
According to what I've found here, it seems that I need to create a trigger(?) and sequence(?) to make the user_id auto increment whenever I add new data into the table. However, I have no idea how to do it.
Here are my questions:
Is my stored procedure right? Are the codes incomplete? I mean, I have not declared the package in the mapper and I've seen that it is needed (?), something like this { CALL [CreateUser].[addUserSP]( blah blah.... Should I write a sequence and trigger or there is an easy way to make the primary key user_id to be auto incremented? Kindly also check the syntax. I have a lot of problems in syntax.
Thank you so much!
To emulate MySQL AUTO_INCREMENT in Oracle, that pattern (as you found) does use a SEQUENCE object and a BEFORE INSERT trigger.
As a demonstration, something like this for the sequence object:
CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 1 ;
And something like this for the before insert trigger:
CREATE TRIGGER users_bi
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
IF :NEW.id IS NULL THEN
SELECT myseq.NEXTVAL INTO :NEW.id FROM DUAL;
END IF;
END
As far as the procedure, I'm not a big fan of extra PL/SQL blocks that wrap a SQL INSERT statement.
It looks like you have an extra semicolon, before RETURNING. That clause is part of the INSERT statement, not a separate statement.
One big gotcha to be aware of is that SQL statements within a PL/SQL block can reference both columns and PL/SQL variables. When variables have the same names as columns, you will likely encounter behavior you didn't expect.
Typically PL/SQL author use a naming convention for variables that reduces the likelihood of name collisions. We frequently see variables with names like v_surname. (Personally, I use a slightly different convention, but the variable names "look like" variable names, not column references. And I don't name columns following the pattern I use for variables.)
The double quotes around the identifiers are acceptable, but this does make the identifiers case sensitive. When identifiers aren't enclosed in double quotes, Oracle treats them as if they were UPPER CASE. Just make sure that your table was defined with lower case column names.

Double quotes inside single quotes in oracle statement

I'm having the following problem with an old database. We migrated from sql to oracle recently and I'm having trouble with an insert statement where the column name is "default". Any ideas (I'm not allowed to change the column name, that would be by far the best solution!)?
It looks somehow like this, only with a billion more columns and it's inside a large if-when-else construction for validating issues, so I can't drop the execute immediate.
EXECUTE IMMEDIATE 'INSERT INTO trytable (ID, "DEFAULT") VALUES (''monkey1'', 0)'
I don't think the problem comes from your column name, as shown in this working example:
SQL> CREATE TABLE trytable (ID VARCHAR2(10), "DEFAULT" NUMBER);
Table created
SQL> BEGIN
2 EXECUTE IMMEDIATE
3 'INSERT INTO trytable (ID, "DEFAULT") VALUES (''monkey1'', 0)';
4 END;
5 /
PL/SQL procedure successfully completed
Technically, you can have a table column name named DEFAULT, even if it's generally a bad idea that will lead to confusion. You will only be able to interact with it through the double-quote " syntax because DEFAULT is a reserved word.
If you specify double quotes around identifiers, Oracle will treat them as case-sensitive, so you have to make sure that they match the table specs.
In your case, it would help to have the specific error message.
The below will executes if your column name is "DEFAULT":
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO TRYTABLE(ID, "DEFAULT")VALUES(''monkey1'',0)';
END;
"DEFAULT" and "default" makes difference.

ORA-01747: invalid user.table.column, table.column, or column specification

Get the above error when the execute immediate is called in a loop
Update CustomersPriceGroups set 1AO00=:disc Where cuno=:cuno
Parameters: disc=66 cuno=000974
Update CustomersPriceGroups set 1AP00=:disc Where cuno=:cuno
Parameters: disc=70.5 cuno=000974
Update CustomersPriceGroups set 1AQ00=:disc Where cuno=:cuno
Parameters: disc=66 cuno=000974
Update CustomersPriceGroups set 1ZA00=:disc Where cuno=:cuno
Parameters: disc=60 cuno=000974
What does this mean ?
Here is the code fragment
c:=PriceWorx.frcPriceListCustomers('020','221');
LOOP
fetch c into comno,cuno,nama,cpls;
exit when c%notfound;
dbms_output.put_Line(cuno);
g:=priceWorx.frcPriceListItemGroups('020','221');
d:=priceworx.frcCustomerDiscounts('020','221',cuno);
loop
fetch g into comno,cpgs,n;
fetch d into comno,cpls,cuno,cpgs,stdt,tdat,qanp,disc,src;
--dbms_output.put(chr(9)||cpgs);
sQ:='Update saap.CustomersPriceGroups set "'|| trim(cpgs)||'"=:disc '
|| ' Where cuno=:cuno';
execute immediate sQ using disc,cuno;
commit;
dbms_output.put_line( sQ );
dbms_output.put_line( chr(9)||'Parameters: disc='|| disc||' cuno='||cuno);
exit when g%notfound;
end loop;
close g;
close d;
end loop;
check your query for double comma.
insert into TABLE_NAME (COLUMN1, COLUMN2,,COLUMN3) values(1,2,3);
(there is extra comma after COLUMN2).
Update: recently (some people have special talents) i succeed to get same exception with new approach:
update TABLE_NAME set COLUMN1=7, set COLUMN2=8
(second SET is redundant)
Unquoted identifiers must begin with an alphabetic character (see rule 6 here). You're trying to assign a value to a column with a name starting with a number 1AO00, 1AP00 etc.
Without seeing the table definition for CustomersPriceGroups we don't know if it has columns with those names. If it does then they must have been created as quoted identifiers. If so you'll have to refer to them (everywhere) with quotes, which is not ideal - makes the code a bit harder to read, makes it easy to make a mistake like this, and can be hard to spot what's wrong. Even Oracle say, on the same page:
Note: Oracle does not recommend using quoted identifiers for database
object names. These quoted identifiers are accepted by SQL*Plus, but
they may not be valid when using other tools that manage database
objects.
In you code you appear to be using quotes when you assign sQ, but the output you show doesn't; but it doesn't have the saap. schema identifier either. That may be because you're not running the version of the code you think, but might just have been
lost if you retyped the data instead of pasting it - you're not showing the earlier output of c.cuno either. But it's also possible you have, say, the case of the column name wrong.
If the execute is throwing the error, you won't see the command being executed that time around the loop because the debug comes after it - you're seeing the successful values, not the one that's breaking. You need to check all the values being returned by the functions; I suspect that g is returning a value for cpgs that actually isn't a valid column name.
As #ninesided says, showing more information, particularly the full exception message, will help identify what's wrong.
It means that the Oracle parser thinks that one of your columns is not valid. This might be because you've incorrectly referenced a column, the column name is reserved word, or because you have a syntax error in the UPDATE statement that makes Oracle think that something which is not a column, is a column. It would really help to see the full statement that is being executed, the definition of the CustomersPriceGroups table and the full text of the exception being raised, as it will often tell which column is at fault.
if you add a extra "," at the end of the set statement instead of a syntax error, you will get ORA-01747, which is very very odd from Oracle
e.g
update table1
set col1 = 'Y', --this odd 1
where col2 = 123
and col3 = 456
In addition to reasons cited in other answers here, you may also need to check that none of your table column names have a name which is considered a special/reserved word in oracle database.
In my case I had a table column name uid. uid is a reserved word in oracle and therefore I was getting this error.
Luckly, my table was a new table and I had no data in it. I was a able to use oracle DROP table command to delete the table and create a new one with a modified name for the problem column.
I also had trouble with renaming the problem column as oracle wouldn't let me and kept throwing errors.
You used oracle keyword in your SQL statement
And I was writing query like. I had to remove [ and ]
UPDATE SN.TableName
SET [EXPIRY_DATE] = systimestamp + INTERVAL '12' HOUR,
WHERE [USER_ID] ='12345'
We recently moved from SQL Server to Oracle.
The cause may also be when you group by a different set of columns than in select for example:
select tab.a, tab.b, count(*)
from ...
where...
group by tab.a, tab.c;
ORA-01747: invalid user.table.column, table.column, or column
specification
You will get when you miss the column relation when you compare both column id your is will not be the same check both id in your database
Here is the sample Example which I was facing:
UPDATE TABLE_NAME SET APPROVED_BY='1000',CHECK_CONDITION=ID, WHERE CONSUMER_ID='200'
here Issue you will get when 'CHECK_CONDITION' and 'ID' both column id will no same
If both id will same this time your query will execute fine, Check id Id both Column you compare in your code.
For me, the issue was due to use to column name "CLUSTER" which is a reserved word in Oracle. I was trying to insert into the column. Renaming the column fixed my issue.
insert into table (JOB_NAME, VERSION, CLUSTER, REPO, CREATE_TS) VALUES ('abc', 169, 'abc.war', '1.3', 'test.com', 'test', '26-Aug-19 04.27.09.000000949 PM')
Error at Command Line : 1 Column : 83
Error report -
SQL Error: ORA-01747: invalid user.table.column, table.column, or column specification
In my case, I had some.* in count. like count(dr.*)

while creating a audit trigger throwing warning as Compilation error

I try to create a audit trigger it throwing compilation error.
could you please help me for creating trigger..
DROP TRIGGER DB.DAT_CAMPLE_REQ_Test;
CREATE OR REPLACE TRIGGER DB."DAT_CAMPLE_REQ_Test"
AFTER insert or update or delete on DAT_CAMPLE_REQ
FOR EACH ROW
declare
dmltype varchar2(6);
BEGIN
if deleting then
INSERT INTO h_dat_cample_req VALUES (
:Old.REQUEST_ID,
:Old.SAMPLE_ID,
:Old.CASSAY_ID,
:Old.CASCADE_ID,
:Old.STATUS_ID,
:Old.AUTHOR,
:Old.CRT_SAE,
:Old.SCREEN_SAE
);
else
if inserting then
dmltype := 'insert';
elsif updating then
dmltype := 'update';
end if;
INSERT INTO h_dat_cample_req VALUES
(
:New.REQUEST_ID,
:New.SAMPLE_ID,
:New.CASSAY_ID,
:New.CASCADE_ID,
:New.STATUS_ID,
:New.AUTHOR,
:New.CRT_SAE,
:New.SCREEN_SAE
);
end if;
END;
You haven't provided the exact error message nor the structure of the table h_dat_cample_req, so I'm afraid I'm going to have to guess.
I suspect the column names in your h_dat_cample_req are not in the order you expect, or there are other columns in the table that you haven't specified a value for in your INSERT statements.
You are using INSERT statements without listing the columns that each value should go in to. The problem with using this form of INSERT statement is that if the columns in the table aren't in exactly the order you think they are, or there are columns that have been added or removed, you'll get an error and it'll be difficult to track it down. Furthermore, if you don't get a compilation error there's still the chance that data will be inserted into the wrong columns. Naming the columns makes it clear which value goes in which column, makes it easier to identify columns that have been removed, and also means that you don't have to specify values for all of the columns in the table - any column not listed gets a NULL value.
I would strongly recommend always naming columns in INSERT statements. In other words, instead of writing
INSERT INTO some_table VALUES (value_1, value_2, ...);
write
INSERT INTO some_table (column_1, column_2, ...) VALUES (value_1, value_2, ...);
Incidentally, you're assigning a value to your variable dmltype but you're not using its value anywhere. This won't cause a compilation error, but it is a sign that your trigger might not be doing quite what you would expect it to. Perhaps your h_dat_cample_req table is a history table and has a column for the type of operation performed?

Resources