Create 'ON UPDATE CASCADE' oracle trigger in Spring Boot - oracle

I'm trying to create something like 'ON UPDATE CASCADE' trigger for oracle db, but I can work with the db just via my Spring Boot backend. My Spring Boot application has just db connection. From db I get (two) tables. And now, when I have the structures of the tables I want to deffine the trigger on BE with the effect to the db but don't know how.
The tables were create like this:
create table tab1(
pk int PRIMARY KEY,
aa int);
create table tab2(
pk int PRIMARY KEY,
tab1_pk int,
FOREIGN KEY(tab1_pk) REFERENCES tab1(pk));
I want to create this trigger:
create or replace trigger tab1_pkUpdate
after update of pk on tab1
for each row
begin
update tab2 s
set s.tab1_pk = :new.pk
where s.tab1_pk = :old.pk;
end;
/

Eventually I have resolved the issue
#Autowired
JdbcTemplate jdbc;
String sql=" create or replace trigger tab1_pkUpdate \n" +
" after update of pk on tab1\n" +
" for each row\n" +
" begin\n" +
" update tab2 s\n" +
" set s.tab1_pk = :new.pk\n" +
" where s.tab1_pk = :old.pk; \n" +
" end;";
jdbc.update(sql);

Related

Can anyone say is it possible to create hive external tables using Java

I am able to create internal tables but i am unable to create external tables hive. Can anyone suggest me whether is it possible or not to create hive external tables.
By doing r & d i came to know that by using CliDriver we can create but there i am unable to create.
Thanks in advance.
Connection connect = DriverManager.getConnection("jdbc:hive2://localhost:10000/userdb","hiveuser","*****");
System.out.println("connected");
java.sql.Statement stmt = connect.createStatement();
/*stmt.executeQuery("CREATE DATABASE ezytrukdb");
System.out.println("Database created successfully.");
*/
String tableName = "SHIPPER";
//ssstmt.executeQuery("drop table" +tableName);
ResultSet res = stmt.executeQuery("CREATE TABLE "+ tableName + " (S_ID INT, S_NAME VARCHAR(100), S_ADDR VARCHAR(100), S_CITY VARCHAR(40))");
String showTable = "SHOW TABLES '"+ tableName + "'";
System.out.println("Running: " +showTable);
res = stmt.executeQuery(showTable);
if(res.next()){
System.out.println(res.getString(1));
}
connect.close();
no difference between hive cli and beeline or java via JDBC to hiveserver2. I think the same sql will get the same result.

adding and subtracting columns in oracle

I have table Inventory
"INVENTORY_CODE" VARCHAR2(20) NOT NULL ENABLE
"ITEM_CODE" VARCHAR2(20) NOT NULL ENABLE
"WAREHOUSE_CODE" VARCHAR2(20)
"CON_TON" NUMBER(38,5)
"IN_Q_TON" NUMBER(38,5)
"OR_Q_TON" NUMBER(38,5)
"RES_TON" NUMBER(38,5)
"RET_TON" NUMBER(38,5)
"ST_INV" NUMBER(38,5)
and another table Inventory_warehouse
"CODE" VARCHAR2(20) NOT NULL ENABLE
"ITEM_CODE" VARCHAR2(20) NOT NULL ENABLE
"QUANTITY_AV_TON" NUMBER(38,5)
"QUANTITY_AV_REAM" NUMBER(38,5)
"QUANTITY_AV_SHEET" NUMBER(38,5)
I want to make a trigger to calculate QUANTITY_AV_TON
as
QUANTITY_AV_TON = IN_Q_TON + RES_TON + RET_TON + ST_INV - CON_TON - OR_Q_TON
I created this trigger but it didn't work
create or replace trigger QUANTITY_TON
AFTER insert or update or delete on INVENTORY
for each row
begin
UPDATE INVENTORY_WAREHOUSE
SET QUANTITY_AV_TON =
select (IN_Q_TON + RES_TON + RET_TON + ST_INV - CON_TON -OR_Q_TON)
from inventory
where INVENTORY.item_code = INVENTORY_WAREHOUSE.item_code;
end;
the values of IN_Q_TON , RES_TON , RET_TON , ST_INV , CON_TON ,OR_Q_TON are calculated from other tables using triggers
If you want to perform the calculation from the context values of the row in the trigger that is being processed. This is normally done by using the ":NEW" variable. I have edited the trigger, but cannot run it, so please try it out. Please read the Oracle Trigger Docs
CREATE OR REPLACE TRIGGER QUANTITY_TON
AFTER INSERT OR UPDATE OR DELETE
ON INVENTORY
FOR EACH ROW
BEGIN
UPDATE INVENTORY_WAREHOUSE
SET QUANTITY_AV_TON = :new.IN_Q_TON
+ :new.RES_TON
+ :new.RET_TON
+ :new.ST_INV
- :new.CON_TON
- :new.OR_Q_TON
WHERE INVENTORY_WAREHOUSE.ITEM_CODE = :new.ITEM_CODE;
END;

Data check during insertion in table

I want to Check the value of data Before insertion in a table.Like ,if things like " or & come in the data,it should ignore it or insert using some escape sequence .
create table test (checkit varchar2(40));
insert into test values("Here is the & test data");
or
insert into test values("Here is the " test data");
Is there a way to do that in oracle?
thanks
EDIT
I want to know the solution especially for Characters like & , " etc not for normal data as shown in the example.
You can do it using BEFORE trigger.
Here is an example replacing & with & and " with "
SET DEFINE OFF;
drop table test;
create table test (checkit varchar2(60));
CREATE OR REPLACE TRIGGER validateTest
BEFORE DELETE OR INSERT OR UPDATE ON test
FOR EACH ROW
BEGIN
:new.checkit := replace(:new.checkit, '&', '&lte;');
:new.checkit := replace(:new.checkit, '"', '"');
END;
/
insert into test (checkit) values ('Here is the & test "data"');
select * from test;
Output:
drop table test succeeded.
create table succeeded.
TRIGGER validateTest Compiled.
1 rows inserted
CHECKIT
------------------------------------------------------------
Here is the &lte; test "data"
1 rows selected
Obviously replacement strings can be whatever.

How to write an Oracle trigger based on Auto incremented value?

I have an Oracle Table with the following keys: ID, Name, DoB, Dept & FileNo. The ID field is the primary Key with an Auto Incremented value.
I wish to write a trigger, so that when a row is added with the Name, DoB & Dept , the FileNo field should get the value yyyy/xxxx where 'yyyy' is a predefined string & 'xxxx' is the value in ID field.
How do I do this?
If it will always be the ID with some prefix, then it probably shouldn't be a column. If that is the default, then a trigger that sets :new.fileno := 'string'||:new.id should suffice.
Oracle doesn't have auto increment, so you probably mean a sequence. If you have a trigger populating that, then this can go in the same trigger.
You need a sequence to implement an Auto Incremented value:
create sequence seq_file_id start with 1 increment by 1;
and a trigger on a table
CREATE TRIGGER file_trg
BEFORE insert
ON file_table
FOR EACH ROW
BEGIN
SELECT seq_file_id.NEXTVAL INTO :new.id FROM dual;
:NEW.fileno := 'yyyy' || :new.id;
END;
/

Auto-increment in Oracle without using a trigger

What are the other ways of achieving auto-increment in oracle other than use of triggers?
You can create and use oracle sequences. The syntax and details are at
http://www.techonthenet.com/oracle/sequences.php
Also read the article
http://rnyb2.blogspot.com/2006/02/potential-pitfall-with-oracle-sequence.html
to understand the limitations with respect to AUTONUMBER in other RDBMS
If you don't need sequential numbers but only a unique ID, you can use a DEFAULT of SYS_GUID(). Ie:
CREATE TABLE xxx ( ID RAW(16) DEFAULT SYS_GUID() )
A trigger to obtain the next value from a sequence is the most common way to achieve an equivalent to AUTOINCREMENT:
create trigger mytable_trg
before insert on mytable
for each row
when (new.id is null)
begin
select myseq.nextval into :new.id from dual;
end;
You don't need the trigger if you control the inserts - just use the sequence in the insert statement:
insert into mytable (id, data) values (myseq.nextval, 'x');
This could be hidden inside an API package, so that the caller doesn't need to reference the sequence:
mytable_pkg.insert_row (p_data => 'x');
But using the trigger is more "transparent".
As far as I can recall from my Oracle days, you can't achieve Auto Increment columns without using TRIGGER. Any solutions out there to make auto increment column involves TRIGGER and SEQUENCE (I'm assuming you already know this, hence the no trigger remarks).
Create a sequence:
create sequence seq;
Then to add a value
insert into table (id, other1, other2)
values (seq.nextval, 'hello', 'world');
Note: Look for oracle docs for more options about sequences (start value, increment, ...)
From 12c you can use an identity column, which makes explicit the link between table and auto-increment; there's no need for a trigger or a sequence. The syntax would be:
create table <table_name> ( <column_name> generated as identity );
In addition to e.g. FerranB's answer:
It is probably worth to mention that, as opposed to how auto_incement works in MySQL:
sequences work database wide, so they can be used for multiple tables and the values are unique for the whole database
therefore: truncating a table does not reset the 'autoincrement' functionaltiy
If you don't really want to use a "trigger-based" solution, you can achieve the auto-increment functionality with a programmatical approach, obtaining the value of the auto increment key with the getGeneratedKeys() method.
Here is a code snippet for your consideration:
Statement stmt = null;
ResultSet rs = null;
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_UPDATABLE);
stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTable");
stmt.executeUpdate("CREATE TABLE autoIncTable ("
+ "priKey INT NOT NULL AUTO_INCREMENT, "
+ "dataField VARCHAR(64), PRIMARY KEY (priKey))");
stmt.executeUpdate("INSERT INTO autoIncTable (dataField) "
+ "values ('data field value')",
Statement.RETURN_GENERATED_KEYS);
int autoIncKeyFromApi = -1;
rs = stmt.getGeneratedKeys();
if (rs.next()) {
autoIncKeyFromApi = rs.getInt(1);
}
else {
// do stuff here
}
rs.close();
source: http://forums.oracle.com/forums/thread.jspa?messageID=3368856
SELECT max (id) + 1
FROM table

Resources