I have one table with a VARCHAR primary key that consists in multiple columns. One of these columns is a VARCHAR that has a maximum of 100 different values.
I want to generate a new table changing this specific VARCHAR column of the PK to an Integer using a sequence, the problem is the sequence I'm using generates a different Id for each row, it doesn't group the different existing Ids.
CREATE SEQUENCE my_seq
MINVALUE 1
START WITH 1
INCREMENT BY 1
How can I make this sequence so it groups the values of the key that are the same on different rows?
You should do this in your test env. first and then only very very carefully when you are 100% certain do it on other systems. we dont have structure or data of your system so you need to fit this general solution to your needs we assume no liability :) .
SQL> create table old_table (object_name varchar2(30), object_type varchar2(19), val_1 varchar2(20), val_2 varchar2(20),
primary key(object_name, object_type));
Table created.
SQL> desc old_table
Name Null? Type
----------------------------------------- -------- ----------------------------
OBJECT_NAME NOT NULL VARCHAR2(30)
OBJECT_TYPE NOT NULL VARCHAR2(19)
VAL_1 VARCHAR2(20)
VAL_2 VARCHAR2(20)
-- you can see this table has your table with composit pk , consists of (object_name and object_type) -- like your table.
SQL> l
1 insert into old_table
2 select object_name, object_type, status, timestamp
3* from all_objects
SQL> /
7289 rows created.
-- we just created some test data --similar to your table data
SQL> l
1 select object_type,count(*)
2 from old_table
3* group by object_type
SQL> /
OBJECT_TYPE COUNT(*)
------------------- ----------
CONSUMER GROUP 2
EDITION 1
SCHEDULE 3
SEQUENCE 13
OPERATOR 45
PROCEDURE 31
WINDOW 9
SCHEDULER GROUP 4
DESTINATION 2
PACKAGE 296
PROGRAM 11
XML SCHEMA 31
TRIGGER 2
JOB CLASS 2
SYNONYM 3974
VIEW 1579
TABLE 96
FUNCTION 163
INDEXTYPE 8
INDEX 21
TYPE 995
EVALUATION CONTEXT 1
22 rows selected.
-- here you can see total rows are 7289 but unique object_types( part of composit pk ) is only 22 distinct values..
SQL> CREATE TABLE NEW_TABLE1(ID NUMBER PRIMARY KEY, OBJECT_TYPE VARCHAR2(19));
Table created.
SQL> DESC NEW_TABLE1
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
OBJECT_TYPE VARCHAR2(19)
SQL>
-- here we created a new table with --id number-- as pk, and your obejct_type as value
CREATE SEQUENCE MY_SEQ MINVALUE 1 START WITH 1 INCREMENT BY 1;
SQL> INSERT INTO NEW_TABLE1
2 SELECT MY_SEQ.NEXTVAL, OBJECT_TYPE FROM (SELECT DISTINCT OBJECT_TYPE FROM OLD_TABLE);
22 rows created.
SQL> SELECT * FROM NEW_TABLE1;
ID OBJECT_TYPE
---------- -------------------
1 CONSUMER GROUP
2 EDITION
3 SCHEDULE
4 SEQUENCE
5 OPERATOR
6 PROCEDURE
7 WINDOW
8 SCHEDULER GROUP
9 DESTINATION
10 PACKAGE
11 PROGRAM
12 XML SCHEMA
13 TRIGGER
14 JOB CLASS
15 SYNONYM
16 VIEW
17 TABLE
18 FUNCTION
19 INDEXTYPE
20 INDEX
21 TYPE
22 EVALUATION CONTEXT
22 rows selected.
-- now we add new column to old/existing table
alter table old_table add (new_number_pk number);
-- update the new column with id/number data
SQL> update old_table set new_number_pk = ( select id from new_table1 where object_type = old_table.object_type);
7289 rows updated.
SQL> select * from old_table where rownum < 20 order by object_type ;
OBJECT_NAME OBJECT_TYPE VAL_1 VAL_2 NEW_NUMBER_PK
------------------------------ ------------------- -------------------- -------------------- -------------
V$FLASHBACK_DATABASE_STAT SYNONYM VALID 2011-08-28:22:11:07 15
V$PARAMETER SYNONYM VALID 2011-08-28:22:11:07 15
V$RESTORE_POINT SYNONYM VALID 2011-08-28:22:11:07 15
V$ROLLNAME SYNONYM VALID 2011-08-28:22:11:07 15
V$ROLLSTAT SYNONYM VALID 2011-08-28:22:11:07 15
V$UNDOSTAT SYNONYM VALID 2011-08-28:22:11:07 15
V$SGA SYNONYM VALID 2011-08-28:22:11:07 15
V$CLUSTER_INTERCONNECTS SYNONYM VALID 2011-08-28:22:11:07 15
V$CONFIGURED_INTERCONNECTS SYNONYM VALID 2011-08-28:22:11:07 15
V$ROWCACHE_SUBORDINATE SYNONYM VALID 2011-08-28:22:11:07 15
V$PARAMETER2 SYNONYM VALID 2011-08-28:22:11:07 15
V$OBSOLETE_PARAMETER SYNONYM VALID 2011-08-28:22:11:07 15
V$SYSTEM_PARAMETER SYNONYM VALID 2011-08-28:22:11:07 15
V$SYSTEM_PARAMETER2 SYNONYM VALID 2011-08-28:22:11:07 15
V$SPPARAMETER SYNONYM VALID 2011-08-28:22:11:07 15
V$PARAMETER_VALID_VALUES SYNONYM VALID 2011-08-28:22:11:07 15
V$ROWCACHE SYNONYM VALID 2011-08-28:22:11:07 15
V$ROWCACHE_PARENT SYNONYM VALID 2011-08-28:22:11:07 15
V_$RESTORE_POINT VIEW VALID 2011-08-28:22:11:07 16
19 rows selected.
-- drop old primary key
SQL> alter table old_table drop primary key;
Table altered.
-- mark object_type column unused in old_table
SQL> alter table old_table set unused column object_type;
Table altered.
-- crate new pk with new column on old_table
SQL> alter table old_table
2 add constraint pk_old_table primary key(object_name, new_number_pk);
Table altered.
-- drop unused column
SQL> alter table old_table drop unused columns;
Table altered.
step 1 - create a new table with all the old PK columns and a new sequence driven one.
step 2 insert into the new table as select distinct columns from the old table
step 3 add a new PK column to the original table.
step 4 update original table with the new PK from the new table where the columns match
Related
For this scenario, I have a table like this: ID (Autoincrement, PK), PartType (VarChar), and DesignItemID (VarChar). I would like to combine the columns ID and PartType into column DesignItemID using a single INSERT statement.
Is this possible?
The purpose for this scenario spawns from trying to use an external SQL database for a part library in Altium Designer. Altium Designer needs a unique ID to maintain a proper link to the part that is placed and the DB. Ordinarily, an autoincrement PK could work, however, I need to keep the different types of parts in separate tables (such at resistors in a resistor table and capacitors in a capacitor table, etc.). So, if I have two or more different tables with an autoincrement PK ID column, I will have multiple IDs all starting at 1.
My proposed solution is to make a table with column ID using autoincrement for the PK, column PartType using a char or varchar, and column DesignItemID also using a char or varchar. Upon an INSERT command, I will enter the value RES for resistor or CAP for capacitor for column PartType and somehow LPAD ID to about 6 places and CONCAT with PartType to create DesignItemID RES000001 or CAP000001 for example. Both tables have 1 as PK ID, but, with the part type and padding, a unique column can be made for Altium Designer.
I understand that in a SQL admin interface, I could structure a query to create this unique piece of data, but Altium Designer requires this unique ID to be in a column.
I can accomplish this task in Access by using a calculate field, but Access is limited to number of concurrent users and cannot scale like an external SQL DB can.
Please note that I will have far more columns in the Database that corresponds to the part. I am only focusing on the columns that I do not know if what I am asking can be done.
depending on your database,
it seems you are asking for a unique number that spans across multiple tables. This could be called ultimately a GUID - if it should also be unique across databases.
this could be done with a single SEQUENCE. or you can look up GUID generators.
exporting multiple tables with such a GUID would be no problem - you just query from wherever they live and send them to your output stream.
Importing on the other hand is more difficult - since you will need to know where each GUID lives (in which table). You can do this with another table that maps each GUID to the table it belongs in.
A little bit of walking instead of just talking. Code you'll see is Oracle, but I guess other databases offer the same or similar options. Note that I don't know Altium Designer.
Question you asked was:
can I combine two or more fields into one field during the same insert statement?
Yes, you can; you already know the operator - it is concatenation. In Oracle, it is either the concat function or double pipe || operator. Here's how.
First, two sample tables (resistors and capacitors):
SQL> create table resistor
2 (id_res varchar2(10) constraint pk_res primary key,
3 name varchar2(10) not null
4 );
Table created.
SQL> create table capacitor
2 (id_cap varchar2(10) constraint pk_cap primary key,
3 name varchar2(10) not null
4 );
Table created.
Sequence will be used to create unique numbers:
SQL> create sequence seqalt;
Sequence created.
Database trigger which creates the primary key value by concatenating a constant (RES for resistors) and the sequence number, left-padded with zeros up to 7 characters in length (so that the full value length is 10 characters):
SQL> create or replace trigger trg_bi_res
2 before insert on resistor
3 for each row
4 begin
5 :new.id_res := 'RES' || lpad(seqalt.nextval, 7, '0');
6 end trg_bi_res;
7 /
Trigger created.
SQL> create or replace trigger trg_bi_cap
2 before insert on capacitor
3 for each row
4 begin
5 :new.id_cap := 'CAP' || lpad(seqalt.nextval, 7, '0');
6 end trg_bi_cap;
7 /
Trigger created.
Let's insert some rows:
SQL> insert into resistor (name) values ('resistor 1');
1 row created.
SQL> select * from resistor;
ID_RES NAME
---------- ----------
RES0000001 resistor 1
Capacitors:
SQL> insert into capacitor (name) values ('capac 1');
1 row created.
SQL> insert into capacitor (name) values ('capac 2');
1 row created.
SQL> select * From capacitor;
ID_CAP NAME
---------- ----------
CAP0000002 capac 1
CAP0000003 capac 2
My suggestion is a view instead of a new table to be used by the Altium Designer - of course, if it is possible (maybe Designer requires a table, and nothing but a table ...):
SQL> create or replace view v_altium (designitemid, name) as
2 select id_res, name from resistor
3 union all
4 select id_cap, name from capacitor;
View created.
SQL> /
View created.
SQL> select * from v_altium;
DESIGNITEM NAME
---------- ----------
RES0000001 resistor 1
CAP0000002 capac 1
CAP0000003 capac 2
You'd now make the Altium Designer read the view and - from my point of view - it should work just fine.
If it has to be a table (let's call it altium), then it would look like this:
SQL> create table altium
2 (designitemid varchar2(10) constraint pk_alt primary key,
3 name varchar2(10)
4 );
Table created.
Triggers will now be changed so that they also insert a row into the altium table (see line #7):
SQL> create or replace trigger trg_bi_res
2 before insert on resistor
3 for each row
4 begin
5 :new.id_res := 'RES' || lpad(seqalt.nextval, 7, '0');
6 insert into altium (designitemid, name) values (:new.id_res, :new.name);
7 end trg_bi_res;
8 /
Trigger created.
SQL> create or replace trigger trg_bi_cap
2 before insert on capacitor
3 for each row
4 begin
5 :new.id_cap := 'CAP' || lpad(seqalt.nextval, 7, '0');
6 insert into altium (designitemid, name) values (:new.id_cap, :new.name);
7 end trg_bi_cap;
8 /
Trigger created.
Let's try it:
SQL> insert into resistor (name) values ('resistor 4');
1 row created.
SQL> insert into resistor (name) values ('resistor 5');
1 row created.
SQL> insert into capacitor (name) values ('capac 5');
1 row created.
Altium table contents reflects contents of resistor and capacitor:
SQL> select * from altium;
DESIGNITEM NAME
---------- ----------
RES0000011 resistor 4
RES0000012 resistor 5
CAP0000013 capac 5
SQL>
However: why do I prefer a view over a table? Because consistency might suffer. What if you delete a row from the capacitor table? You'd have to delete appropriate row from the new altium table as well, and vice versa.
You can't create a foreign key constraint from the altium table to reference primary keys in other tables because as soon as you try to insert a row into the altium table that references resistor, it would fail as there's no such a primary key in capacitor. You can create constraints, but - that's pretty much useless:
SQL> drop table altium;
Table dropped.
SQL> create table altium
2 (designitemid varchar2(10) constraint pk_alt primary key,
3 name varchar2(10),
4 --
5 constraint fk_alt_res foreign key (designitemid) references resistor (id_res),
6 constraint fk_alt_cap foreign key (designitemid) references capacitor (id_cap)
7 );
Table created.
OK, table was successfully created, but - will it work?
SQL> insert into resistor (name) values ('resistor 7');
insert into resistor (name) values ('resistor 7')
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.FK_ALT_CAP) violated - parent key not
found
ORA-06512: at "SCOTT.TRG_BI_RES", line 3
ORA-04088: error during execution of trigger 'SCOTT.TRG_BI_RES'
SQL>
Nope, it won't as such a primary key doesn't exist in the capacitor table.
It means that you'd have to maintain consistency manually, and that's always tricky.
Therefore, if possible, use a view.
Good evening to you all.
I'm using groovy java and I'm trying to create a table inside the oracle database.
I know that I can do that in two times.
first place, create the table and then insert the variables that are coming from my Array output.
This is my Array:
[[Paulo, Alves, Ducati, 33, London, Valentino Rossi]]
This is my table:
// sql scriptcreates a table
def createTableScript = """
CREATE TABLE MOTOGP(
FIRST_NAME VARCHAR(50),
LAST_NAME VARCHAR(50),
AGE NUMBER,
ADDRESS VARCHAR(50),
ALIAS VARCHAR(50)
)"""
// execute the create table script
sql.execute(createTableScript);
I want to pass my variables or Arry objects to the table at the same time as the creation. It is possible?
Thank you in advance!
I don't know Groovy, but - based on what you described - perhaps it is CTAS (Create Table As Select) you're looking for. In Oracle, it looks like this:
SQL> create table motogp as
2 select cast('Paulo' as varchar2(20)) first_name,
3 cast('Alves' as varchar2(20)) last_name,
4 33 age,
5 cast('London' as varchar2(20)) address,
6 cast('Valentino Rossi' as varchar2(20)) alias
7 from dual;
Table created.
SQL>
The result is then:
SQL> desc motogp
Name Null? Type
----------------------------- -------- --------------------
FIRST_NAME VARCHAR2(20)
LAST_NAME VARCHAR2(20)
AGE NUMBER
ADDRESS VARCHAR2(20)
ALIAS VARCHAR2(20)
SQL> select * From motogp;
FIRST_NAME LAST_NAME AGE ADDRESS ALIAS
-------------------- -------------------- ---------- -------------------- --------------------
Paulo Alves 33 London Valentino Rossi
SQL>
Note CASTs I used; without it, table's columns would have length equal to current column values and different datatype (CHAR instead of VARCHAR2) and that's probably not what you'd want to have. For example:
SQL> create table motogp as
2 select 'Paulo' first_name
3 from dual;
Table created.
SQL> desc motogp;
Name Null? Type
----------------------------- -------- --------------------
FIRST_NAME CHAR(5)
SQL>
Now, how to do that in Groovy, no idea; I hope that this is good enough to get you started.
So I am working on my coursework and I am sort of stuck as to what to do for this one part. The question is this :
Flatpack(FlatpackID, Name, Colour, Type, UnitPrice)
FlatpackID should be generated by the DBMS
Name has at most 20 characters and should be not null
Colour is optional
Type is one of (Office, Kitchen, Bedroom, General)
UnitPrice should be between 5.00 and 500.00
Okay so the one I need help with is the one that is in bold/italic i.e. "Type is one of (Office, Kitchen, Bedroom, General")
How exactly am I declaring this within my
CREATE TABLE FLATPACK (
);
I asked and I was told it is only allowed those values and nothing else.
Any help would be greatly appreciated! Thanks
One method is a check constraint:
constraint chk_flatpack_type check ( Type in ('Office', 'Kitchen', 'Bedroom', 'General') );
Another option is to set up foreign key constraint to a reference table, and have the reference table only contain these values.
This is one option (having types restricted by a check constraint):
SQL> CREATE TABLE flatpack
2 (
3 flatpackid NUMBER CONSTRAINT pk_fp PRIMARY KEY,
4 name VARCHAR2 (20) NOT NULL,
5 colour VARCHAR2 (20),
6 TYPE VARCHAR2 (20)
7 CONSTRAINT ch_ty CHECK
8 (TYPE IN ('Office',
9 'Kitchen',
10 'Bedroom',
11 'General')),
12 unitprice NUMBER CONSTRAINT ch_pr CHECK (unitprice BETWEEN 5 AND 500)
13 );
Table created.
SQL>
Another, better (why? More flexible, as you can add any type you want, without altering the table) option is to create a table which will be referenced by the TYPE column:
SQL> CREATE TABLE flatpack_type (TYPE VARCHAR2 (20) CONSTRAINT pk_ty PRIMARY KEY);
Table created.
SQL> CREATE TABLE flatpack
2 (
3 flatpackid NUMBER CONSTRAINT pk_fp PRIMARY KEY,
4 name VARCHAR2 (20) NOT NULL,
5 colour VARCHAR2 (20),
6 TYPE VARCHAR2 (20)
7 CONSTRAINT fk_fp_ty REFERENCES flatpack_type (TYPE),
8 unitprice NUMBER CONSTRAINT ch_pr CHECK (unitprice BETWEEN 5 AND 500)
9 );
Table created.
SQL> insert into flatpack_type --> valid values
2 select 'Office' from dual union all
3 select 'Kitchen' from dual union all
4 select 'Bedroom' from dual union all
5 select 'Genral' from dual;
4 rows created.
As of the ID, you could use an identity column (if on 12c or higher), or a standard option for lower versions - a trigger which uses a sequence:
SQL> create sequence seq_fp;
Sequence created.
SQL> create or replace trigger trg_bi_fp
2 before insert on flatpack
3 for each row
4 begin
5 :new.flatpackid := seq_fp.nextval;
6 end;
7 /
Trigger created.
SQL>
I am trying to create some triggers and procedures to auto populate some tables in my database. I have two tables, Users and Utilities.
Users Table:
CREATE TABLE USERS (
User_id Number(38,0) NOT NULL PRIMARY KEY,
User_name char(18) NULL ,
Storage_Size varchar(18) NULL ,
Memory_Usage Number(38,0) NULL
);
Utilities Table
CREATE TABLE UTILITIES (
Utility_id Number(38,0) NOT NULL PRIMARY KEY,
Utility_Name varchar(18) NULL ,
Utility_Cost Number(38,0) NULL ,
Running char(4) NULL ,
User_id Number(38,0) NULL ,
);
Now what I would like to take place in my DB.
When a User is INSERTED into USERS table it fires off a trigger.
This trigger will then insert a bunch of Utilities into the UTILITIES table (User_ID will match the User_ID that was just created) for the User that was created.
After Utilities have been inserted into UTILITIES table I would then like to run a procedure that will SUM(Utility_Cost) in the UTILITIES table and store the SUM in USERS.Memory_Usage WHERE the USER_ID matches.
What I have created so far:
Trigger to fire after INSERT on USERS table:
CREATE OR REPLACE TRIGGER users_after_insert
AFTER INSERT ON USERS
BEGIN
INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, UTILITY_COST)
VALUES
('Javaw.exe', 'YES', :new.USER_ID, seq_utility_id.nextval
, round(dbms_random.value(25000, 100000)));
sum_data();
END;
Procedure to be called from trigger:
CREATE OR REPLACE PROCEDURE sum_data
IS
BEGIN
UPDATE USERS
SET MEMORY_USAGE = (SELECT SUM(UTILITY_COST)
FROM UTILITIES
WHERE USERS.USER_ID = UTILITIES.USER_ID)
WHERE USERS.User_id = :new.User_id;
END;
However when I try and INSERT into the USERS table I get:
ORA-04091: table STUDENT052.USERS is mutating, trigger/function may not see it
ORA-06512: at "STUDENT052.SUM_DATA", line 4
ORA-06512: at "STUDENT052.USERS_AFTER_INSERT", line 5
ORA-04088: error during execution of trigger 'STUDENT052.USERS_AFTER_INSERT'
Does anyone have any idea why this is happening? Any information would be greatly appreciated. Thanks!
You will have to call the procedure separately and update the table, since the data is still not committed and the procedure will try update the same table, it wont work. Apart from that I have executed the trigger and it will populate your utilities table.
SQL> CREATE TABLE USERS (
2 User_id Number(38,0) NOT NULL PRIMARY KEY,
3 User_name char(18) NULL ,
4 Storage_Size varchar(18) NULL ,
5 Memory_Usage Number(38,0) NULL
6 );
Table created.
SQL> CREATE TABLE UTILITIES (
2 Utility_id Number(38,0) NOT NULL PRIMARY KEY,
3 Utility_Name varchar(18) NULL ,
4 Utility_Cost Number(38,0) NULL ,
5 Running char(4) NULL ,
6 User_id Number(38,0) NULL
7 );
Table created.
SQL> CREATE SEQUENCE seq_utility
2 MINVALUE 1
3 MAXVALUE 100
4 START WITH 1
5 INCREMENT BY 1
6 CACHE 5;
Sequence created.
SQL> CREATE OR REPLACE PROCEDURE sum_data ( user_id number) is
2 luser_id number:=user_id;
3 BEGIN
4 UPDATE USERS
5 SET MEMORY_USAGE = (SELECT SUM(UTILITY_COST) FROM UTILITIES WHERE USERS.USER_ID =luser_id);
6 END;
7 /
Procedure created.
SQL> CREATE OR REPLACE TRIGGER users_after_insert
2 AFTER INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, UTILITY_COST)
6 VALUES
7 ('Javaw.exe', 'YES', :New.USER_ID, seq_utility_id.nextval, round(dbms_random.value(25000, 100000)));
8 --sum_data(:New.USER_ID);
9 END;
10
11 /
Trigger created.
SQL> insert into users (user_id,user_name) values (125,'TESTUSER');
1 row created.
SQL> select * from utilities;
UTILITY_ID UTILITY_NAME UTILITY_COST RUNN USER_ID
---------- ------------------ ------------ ---- ----------
4 Javaw.exe 68271 YES
5 Javaw.exe 62481 YES 124
10 Javaw.exe 60727 YES 125
SQL> select * from users;
USER_ID USER_NAME STORAGE_SIZE MEMORY_USAGE
---------- ------------------ ------------------ ------------
123 TESTUSER
124 TESTUSER
125 TESTUSER
EDIT
SQL> CREATE OR REPLACE TRIGGER users_after_insert
2 AFTER INSERT ON USERS
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, UTILITY_COST)
6 VALUES
7 ('Javaw.exe', 'YES', :New.USER_ID, seq_utility_id.nextval, round(dbms_random.value(25000, 100000)));
8 commit;
9 sum_data(:New.USER_ID);
10 END;
11
12 /
Trigger created.
SQL> insert into users (user_id,user_name) values (126,'TESTUSER');
insert into users (user_id,user_name) values (126,'TESTUSER')
*
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SCOTT.USERS_AFTER_INSERT", line 5
ORA-04088: error during execution of trigger 'SCOTT.USERS_AFTER_INSERT'
A commit within autonomous pragma transaction:
SQL> CREATE OR REPLACE TRIGGER users_after_insert
2 AFTER INSERT ON USERS
3 FOR EACH ROW
4 declare
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 BEGIN
7 commit;
8 INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, UTILITY_COST)
9 VALUES
10 ('Javaw.exe', 'YES', :New.USER_ID, seq_utility_id.nextval, round(dbms_random.value(25000, 100000)));
11 sum_data(:New.USER_ID);
12 END;
13
14 /
Trigger created.
SQL> insert into users (user_id,user_name) values (126,'TESTUSER');
insert into users (user_id,user_name) values (126,'TESTUSER')
*
ERROR at line 1:
ORA-06519: active autonomous transaction detected and rolled back
ORA-06512: at "SCOTT.USERS_AFTER_INSERT", line 9
ORA-04088: error during execution of trigger 'SCOTT.USERS_AFTER_INSERT'
EDIT2
SQL> create view users_views as select a.user_id,a.user_name,SUM(p.UTILITY_COST) as "memory_usage"
2 from users a,utilities p where a.user_id=p.user_id group by a.user_id,a.user_name;
View created.
SQL> select * from users_views;
USER_ID USER_NAME memory_usage
---------- ------------------ ------------
125 TESTUSER 60727
124 TESTUSER 62481
SQL>
Yes, read up on mutating triggers. You're trying to update a record being inserted at the same time, and if you're trying to insert multiple utilities, well, it becomes a real mess.
Why not instead create a view on the tables that includes a column computing the memory usage? Or try a virtual column (or function-based column) on the users table that's based on the other table. (I haven't tested that across tables, so I can't say whether it would work or not.)
I'm doing a method that inserts into the table which has a unique column. What I don't know is if I can access the insert value that made the insert fail.
For example:
table1(id,name, phone);
name is unique.
insert (1,a,123);
insert (2,a,1234);
What I want is when I do the second insert I to return the id value '1' without having to recur to a query.
Thank you in advance.
From oracle 10g r2 you can use log errors clause of insert command to log errors in a separate table. Here is an example:
SQL> create table test_table(
2 id number primary key,
3 col1 varchar2(7)
4 )
5 ;
Table created
-- creates a table for logging errors (table name will be prefaced with err$_)
SQL> begin dbms_errlog.create_error_log('TEST_TABLE'); end;
2 /
PL/SQL procedure successfully completed
-- violates primary key constraint
SQL> insert into test_table(id, col1)
2 ( select 1, level
3 from dual
4 connect by level <= 3)
5 log errors reject limit unlimited;
1 row inserted
SQL> commit;
SQL> select * from test_table;
ID COL1
---------- -------
1 1
SQL> select * from err$_test_table;
ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ ID COL1
--------------- ------------------------------------------------------------------------------------------------------------
1 ORA-00001: unique constraint (HR.SYS_C008315) violated I 1 2
1 ORA-00001: unique constraint (HR.SYS_C008315) violated I 1 3
maybe you can write a trigger(before insert) on your table, on which insert about to happen. In this you can check if the column value(name) already exists in table.
In case it does you may insert this duplicate record in another table for further reference
Another approach is to write the insert in a procedure where the name may be checked and the duplicate name could be stored in a table.
Hope it helps