Getting error :Error(2,3): PL/SQL: SQL Statement ignored Error(8,5): PL/SQL: ORA-00984: column not allowed here - plsql

My code is like below.
create table XXINF_DB_OBJECT_DDL_LOG (
EVENT_DATE DATE NOT NULL,
EVENT_TIMESTAMP TIMESTAMP NOT NULL,
EVENT_TYPE VARCHAR2(30) NOT NULL,
OBJECT_TYPE VARCHAR2(30) NOT NULL,
OBJECT_OWNER VARCHAR2(30) NOT NULL,
OBJECT_NAME VARCHAR2(30) NOT NULL,
DB_USER VARCHAR2(30) NOT NULL,
OS_USER VARCHAR2(100) ,
HOST_NAME VARCHAR2(100),
HOST_IP_ADDRESS VARCHAR2(30)
);
create or replace trigger XXINF_DB_OBJECT_DDL_LOG_AUDIT
AFTER DDL ON schema
begin
insert into XXINF_DB_OBJECT_DDL_LOG values(
sysdate,
systimestamp,
ora_sysevent,
ora_dict_obj_type,
ora_dict_obj_owner,
ora_dict_odj_name,
ora_login_user,
SYS_CONTEXT('USERENV','OS_USER'),
SYS_CONTEXT('USERENV','TERMINAL'),
SYS_CONTEXT('USERENV','IP_ADDRESS')
);
END;
/
when I execute get error:
Error(2,3): PL/SQL: SQL Statement ignored Error(8,5): PL/SQL:
ORA-00984: column not allowed here

Please use the corrections as below:
create or replace trigger XXINF_DB_OBJECT_DDL_LOG_AUDIT
AFTER DDL ON SCHEMA
begin
insert into XXINF_DB_OBJECT_DDL_LOG
(
EVENT_DATE,
EVENT_TIMESTAMP,
EVENT_TYPE,
OBJECT_TYPE,
OBJECT_OWNER,
OBJECT_NAME,
DB_USER,
OS_USER,
HOST_NAME,
HOST_IP_ADDRESS
)
values
(
sysdate,
systimestamp,
ora_sysevent,
ora_dict_obj_type ,
ora_dict_obj_owner,
ora_dict_obj_name ,
ora_login_user ,
SYS_CONTEXT('USERENV','OS_USER'),
SYS_CONTEXT('USERENV','TERMINAL'),
SYS_CONTEXT('USERENV','IP_ADDRESS') );
END;
/

Related

Insert Data into SQL Table with primary key column

I have a table in a SQL Server database and an R script that appends data to that tabl.
The db table contains a primary key ("ID"), which is just a scope_identity field
When I try to append the table into that location, I keep running into the following error
> sqlSave(Conn[["DbCon"]],
+ dat = OutputDataFinal,
+ tablename = "DataSci_StandardTransferPriority",
+ verbose = TRUE,
+ append = TRUE,
+ rownames = FALSE)
Query:
INSERT INTO "DataSci_StandardTransferPriority" (
"ID", "LeadSourceName", "AgeCategory", "ZipColor", "LeadCount_Sum",
"OB_TotalDials_Sum", "ContactRate", "TransferRate", "HypTransfers", "LaborCPT",
"MarketingCpt", "CloseRate", "PDLTR", "Policy_Count_Sum", "InboundDials_Sum",
"LeadCost_Sum", "PPT", "PPH", "ContactRateXCloseRate", "ContactRateXCloseRateTarget",
"ModelValue", "SourcePriority", "InsertTS"
)
VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )
Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
missing columns in 'data'
How can I append and ignore the issue with the primary key?
In standard INSERT operation dont specify identity column. It automatically provides next incremental identity value. For example:
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES
('first insert', 50.2),
('second insert', 84.2);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
The result was:
ID
Column1
Column2
1
first insert
50.200
2
second insert
84.200
If you want insert on identity column any way - enable IDENTITY_INSERT. But be care for data integrity issues.
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('first insert', 50.2);
SET IDENTITY_INSERT #TempTable ON;
INSERT INTO #TempTable (
[ID],
[Column1],
[Column2]
)
VALUES
(4, 'second insert', 84.63),
(2, 'third insert', 99.56);
SET IDENTITY_INSERT #TempTable OFF;
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('four insert', 100.32);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
And the result:
ID
Column1
Column2
1
first insert
50.200
2
third insert
99.560
4
second insert
84.630
5
four insert
100.320

Create index if not exist

ALL,
SQL> SELECT 1 FROM all_indexes WHERE table_name = UPPER( 'abcatcol' ) AND index_name = UPPER( 'abcatcol_tnam_ownr_cnam' );
no rows selected
SQL> CREATE INDEX abcatcol_tnam_ownr_cnam ON abcatcol(abc_tnam, abc_ownr, abc_cnam);
CREATE INDEX abcatcol_tnam_ownr_cnam ON abcatcol(abc_tnam, abc_ownr, abc_cnam)
*
ERROR at line 1:
ORA-01408: such column list already indexed
SQL> SELECT 1 FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );
1
----------
1
SQL> SELECT index_name FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );
INDEX_NAME
------------------------------
SYS_C007087
SQL >
What am I missing? Why can't I create an index?
EDIT:
SQL> select index_name, listagg(column_name, ', ') within group(order by 1)-- over(partition by index_name)
2 from dba_ind_columns
3 where table_name = 'ABCATCOL'
4 group by index_name;
INDEX_NAME
------------------------------
LISTAGG(COLUMN_NAME,',')WITHINGROUP(ORDERBY1)--OVER(PARTITIONBYINDEX_NAME)
--------------------------------------------------------------------------------
SYS_C007087
ABC_CNAM, ABC_OWNR, ABC_TNAM
SQL> SELECT index_name FROM all_indexes WHERE table_name = UPPER( 'abcatcol' );
INDEX_NAME
------------------------------
SYS_C007087
SQL>
EDIT2:
The suggested question utilizes PL/SQL. I want to understand how to do that using standard SQL and why my queries do not work as expected.
EDIT3:
This is the table definition:
CREATE TABLE abcatcol(abc_tnam char(129) NOT NULL, abc_tid integer, abc_ownr char(129) NOT NULL, abc_cnam char(129) NOT NULL, abc_cid smallint, abc_labl char(254), abc_lpos smallint, abc_hdr char(254), abc_hpos smallint, abc_itfy smallint, abc_mask char(31), abc_case smallint, abc_hght smallint, abc_wdth smallint, abc_ptrn char(31), abc_bmap char(1), abc_init char(254), abc_cmnt char(254), abc_edit char(31), abc_tag char(254), PRIMARY KEY( abc_tnam, abc_ownr, abc_cnam ));
So I guess since those fields are part of the PK Otacle already made the index, right?
You are looking for an index by it's name whereas oracle says to you this set of columns has been already indexed.
It means there is already an index with another name over that column set.
You need to check against dba_ind_columns table to get the index name over that column set
UPD. Here is the query to help you out to find the columns indexed
select index_name, listagg(column_name, ', ') within group(order by 1)-- over(partition by index_name)
from dba_ind_columns
where table_name = 'TABLE_NAME'
group by index_name;

Create table and then insert data into the new table from another table

I am creating one table name emp_inforamtion with checking that table is exist in database or not ,and if not then creating table then inserting the data from bank table in to emp_information table.
DECLARE
ncount NUMBER;
v_sql VARCHAR2(4000);
CURSOR c1
IS
SELECT bank_code,
center_code,
bank_name,
logo
FROM bank
WHERE bank_code ='607143';
BEGIN
SELECT COUNT(1) INTO ncount FROM tab WHERE tname LIKE '%EMP_INFORMATION%';
IF (ncount <= 0) THEN
DBMS_OUTPUT.PUT_LINE (ncount || 'count');
BEGIN
v_sql :=' CREATE TABLE EMP_INFORMATION
(
emp_id VARCHAR2(3),
emp_name VARCHAR2(20),
emp_salary VARCHAR2(3),
emp_department VARCHAR2(3)
)';
EXECUTE immediate v_sql;
COMMIT;
BEGIN
FOR i IN c1
LOOP
INSERT
INTO EMP_INFORMATION
(
emp_id,
emp_name,
emp_salary,
emp_department
)
VALUES
(
i.bank_code,
i.bank_name,
i.center_code,
i.logo
);
END LOOP;
END;
END;
END IF;
end;
/
found below error after executing the above cursor:
ORA-06550: line 30, column 16: PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 29, column 11: PL/SQL: SQL Statement ignored
When you create a table using execute immediate in an anonymous block, use execute immediate to insert the data into it.
DECLARE
ncount NUMBER;
v_sql VARCHAR2(4000);
CURSOR c1
IS
SELECT bank_code,
center_code,
bank_name,
logo
FROM bank
WHERE bank_code ='607143';
BEGIN
SELECT COUNT(1) INTO ncount FROM tab WHERE tname LIKE '%EMP_INFORMATION%';
IF (ncount <= 0) THEN
DBMS_OUTPUT.PUT_LINE (ncount || 'count');
BEGIN
v_sql :=' CREATE TABLE EMP_INFORMATION
(
emp_id VARCHAR2(3),
emp_name VARCHAR2(20),
emp_salary VARCHAR2(3),
emp_department VARCHAR2(3)
)';
EXECUTE IMMEDIATE v_sql;
BEGIN
FOR i IN c1
LOOP
EXECUTE IMMEDIATE 'INSERT
INTO EMP_INFORMATION
(
emp_id,
emp_name,
emp_salary,
emp_department
)
VALUES
(
:a,
:b,
:c,
:d
)' using i.bank_code, i.bank_name, i.center_code, i.logo;
END LOOP;
END;
END;
END IF;
end;
/

Oracle PLSQL update table where in Associative Array?

I would like to, in a stored proc, update all the records that match an id.
Now, this list of id, is being passed in as a table of varchar (Associative Array)..
CREATE TYPE varcharArray AS TABLE OF VARCHAR2(1000) index by ...
and the proc declaration is something like
PROCEDURE testProc (p_IDs in varcharArray, p_Success out Number)
and the update statement in the proc
update testtable
set col = 'val'
where id in (select column_value from table(p_IDs);
This doesn't seem to work. So i had to do a loop in the array and update for each Id.
But i'd really like it to update using the where in clause.. Any help would be great.
PS: the id field is a number.
It works for me:
create table testtable (col varchar2(10), id varchar2(1000));
insert into testtable values (null, 'AAA');
insert into testtable values (null, 'BBB');
insert into testtable values (null, 'CCC');
insert into testtable values (null, 'DDD');
commit;
create or replace PROCEDURE testProc (p_IDs in varcharArray) is
begin
update testtable
set col = 'val'
where id in (select column_value from table(p_IDs));
end;
/
exec testproc(p_ids=>varcharArray('AAA','DDD'));
SQL> select * from testtable;
COL ID
---------- ----------
val AAA
BBB
CCC
val DDD

PL/SQL: Statement ignored

create or replace trigger perform_validations
after insert or update on xx_hr_employee
for each row
begin
validation;
END;
/
and my procedure validation is:
declare
E_ID xx_hr_employee.emp_id%type;
E_NAME xx_hr_employee.emp_name%type;
D_ID xx_hr_employee.dept_id%type;
D_NAME xx_hr_employee.dept_name%type;
S_ID xx_hr_employee.supervisor_id%type;
S_NAME xx_hr_employee.supervisor_name%type;
P_ID xx_hr_employee.project_id%type;
P_NAME xx_hr_employee.project_name%type;
SAL xx_hr_employee.salary%type;
A xx_hr_employee.age%type;
l_count number;
e_count number;
procedure validation
is
cursor my_cursor is
select EMP_ID, EMP_NAME, DEPT_ID, DEPT_NAME, SUPERVISOR_ID, SUPERVISOR_NAME, PROJECT_ID, PROJECT_NAME, SALARY, AGE
from xx_hr_employee E;
begin
open my_cursor;
loop
fetch my_cursor into E_ID, E_NAME, D_ID, D_NAME, S_ID, S_NAME, P_ID, P_NAME, SAL, A;
exit when my_cursor%notfound;
if(E_ID = 0000) then
insert into xx_stg_hr_employee( EMP_ID, EMP_NAME, DEPT_ID, DEPT_NAME, SUPERVISOR_ID, SUPERVISOR_NAME, PROJECT_ID, PROJECT_NAME, SALARY, AGE)
select EMP_ID, EMP_NAME, DEPT_ID, DEPT_NAME, SUPERVISOR_ID, SUPERVISOR_NAME, PROJECT_ID, PROJECT_NAME, SALARY, AGE from xx_hr_employee
where emp_id <> 0000;
end if;
end loop;
close my_cursor;
delete from xx_stg_hr_employee WHERE (Emp_name like '% %');
UPDATE xx_stg_hr_employee SET mycol=seq_id3.NEXTVAL;
Select count(*) into l_count From xx_hr_employee
Group By EMP_ID, EMP_NAME, DEPT_ID, DEPT_NAME, SUPERVISOR_ID, SUPERVISOR_NAME, PROJECT_ID, PROJECT_NAME, SALARY, AGE
Having Count(*) > 1;
if(l_count <> 0) then
delete from xx_stg_hr_employee where mycol NOT IN (SELECT MIN(mycol)
FROM xx_stg_hr_employee GROUP BY EMP_ID, EMP_NAME, DEPT_ID, DEPT_NAME, SUPERVISOR_ID, SUPERVISOR_NAME, PROJECT_ID, PROJECT_NAME, SALARY, AGE);
end if;
end;
begin
validation;
end;
/
it is showing Error at line 2: PL/SQL: Statement ignored..
here validation is a procedure which should get called when any insert(or update) is performed on xx_hr_employee..
I don't know how to proceed further.
I am using oracle apex.
i've tested the following and it worked for me, so please see what you missed:
For example
Your table is like Create table TEST_TABLE (X Number);
Then your stored procedure is
CREATE OR REPLACE PROCEDURE VALIDATIONS IS
BEGIN
--Do your validation over here..
UPDATE TEST_TABLE SET X = 1;
END;
then your code should work as you written:
CREATE OR REPLACE TRIGGER PERFORM_VALIDATIONS
AFTER INSERT OR UPDATE ON TEST_TABLE
FOR EACH ROW
BEGIN
VALIDATIONS;
END;
/
Important: If you create the procedure in a package, then make sure that the Package head has the declaration, and then call it like YourPackageName.VALIDATIONS instead of VALIDATIONS only

Resources