I am trying to update the TEMP table which I created during the session.
After TEMP table creation, I wanted to update few records but Big query is throwing error.
BEGIN TRANSACTION;
CREATE OR REPLACE TEMP TABLE working_table
AS
SELECT 1 as ID , 'ABC' as NAME;
SELECT * FROM working_table;
UPDATE working_table
SET ID = 2 Where TRUE;
SELECT * FROM working_table;
COMMIT TRANSACTION;
delete the records from TEMP table will give the same issue.
Related
I have a table called GSH where values already exists.
Have added a new column named 'GS' in the table 'GSH'.I have to add values to the newly added column only for the first thousand rows selected from GSH table.
How to write the SQL query?
If I followed you correctly, you want to add data in the column for random 1000 rows. (Update value of the newly column)
Update GSH
SET GS = 1 -- replace 1 with value that you want to fill it with
WHERE ROWNUM <= 1000;
Cheers!!
You can use below (assuming you want to pick any 100 rows)
update GSH
set GS = 'your values logic'
where rowid in (
select rowid
from GSH
where rownum < 101);
This is the script I used to recreate your scenario
drop table temp;
create table temp (temp1 varchar2(100));
begin
for rec in 1..500
loop
insert into temp values('s');
end loop;
commit;
end;
/
alter table temp add temp2 varchar2(200);
update temp
set temp2 = 'your values logic'
where rowid in (
select rowid
from temp
where rownum < 101);
I want a trigger that updates the value of a column, but I just want to update a small set of rows that depends of the values of the inserted row.
My trigger is:
CREATE OR REPLACE TRIGGER example
AFTER INSERT ON table1
FOR EACH ROW
BEGIN
UPDATE table1 t
SET column2 = 3
WHERE t.column1 = :new.column1;
END;
/
But as I using FOR EACH ROW I have a problem when I try it, I get the mutating table runtime error.
Other option is not to set the FOR EACH ROW, but if I do this, I dont know the inserted "column1" for comparing (or I dont know how to known it).
What can I do for UPDATING a set of rows that depends of the last inserted row?
I am using Oracle 9.
You should avoid the DML statements on the same table as defined in a trigger. Use before DML to change values of the current table.
create or replace trigger example
before insert on table1
for each row
begin
:new.column2 := 3;
end;
/
You can modify the same table with pragma autonomous_transaction:
create or replace trigger example
after insert on table1 for each row
declare
procedure setValues(key number) is
pragma autonomous_transaction;
begin
update table1 t
set column2 = 3
where t.column1 = key
;
end setValues;
begin
setValues(:new.column1);
end;
/
But I suggest you follow #GordonLinoff answere to your question - it's a bad idea to modify the same table in the trigger body.
See also here
If you need to update multiple rows in table1 when you are updating one row, then you would seem to have a problem with the data model.
This need suggests that you need a separate table with one row per column1. You can then fetch the value in that table using join. The trigger will then be updating another table, so there will be no mutation problem.
`create table A
(
a INTEGER,
b CHAR(10)
);
create table B
(
b CHAR (10),
d INTEGER
);
create trigger trig1
AFTER INSERT ON A
REFERENCING NEW AS newROW
FOR EACH ROW
when(newROW.a<=10)
BEGIN
INSERT into B values(:newROW.b,:newROW.a);
END trig1;
insert into A values(11,'Gananjay');
insert into A values(5,'Hritik');
select * from A;
select * from B;`
I have a SP that INSERT INTO TBL_DOMAIN from TBL_STAGING, but first I want check table TBL_STAGING to make sure the table is not empty before I truncate table TBL_DOMAIN, if table TBL_STAGING got more than one record then proceed the truncate table TBL_DOMAIN then run the INSERT, ELSE message say the table TBL_STAGING is EMPTY and exit the SP. My goal is to make sure the table TBL_DOMAIN still have the data even is old. I'm very new SQL please help.
CREATE PROCEDURE [dbo].[SP_INSERT_ALL_DOMAIN]
WITH EXECUTE AS CALLER
AS
BEGIN
BEGIN TRANSACTION NT_ALL_DOMAIN
INSERT INTO TBL_DOMAIN
(DOMAIN_NAME,
DISTINGUISHED_NAME,
EMAIL_ADDR_I)
SELECT DOMAIN_NAME,
DISTINGUISHED_NAME,
EMAIL_ADDR_I
FROM TBL_STAGING
First you need to check if TBL_STAGING has data:
IF EXISTS (SELECT TOP 1 1 FROM TBL_STAGING)
BEGIN
BEGIN TRANSACTION NT_ALL_DOMAIN
INSERT INTO TBL_DOMAIN
(DOMAIN_NAME,
DISTINGUISHED_NAME,
EMAIL_ADDR_I)
SELECT DOMAIN_NAME,
DISTINGUISHED_NAME,
EMAIL_ADDR_I
FROM TBL_STAGING
COMMIT
END
ELSE
BEGIN
RETURN 'no data on table'
END
How can I insert the rows deleted in a delete statement into a new table within a stored procedure in DB2 SQL?
DB2 allows the following syntax to return the deleted rows:
select * from old table (
delete from my_table where foo > 1
)
For some reason, you can't just do an insert based on the results returned from that statement. However, you can use common table expressions as a kludgy workaround:
with deleted as (
select * from old table (delete from my_table where foo > 1)
)
select * from new table (insert into archive_table select * from deleted)
This has an unnecessary extra select statement that I don't want, but at least it works. Deleted rows get inserted into another table.
However, how can I do this within a stored procedure?
A stored procedure doesn't allow a bare select statement. I thought of putting it within a set statement:
set my_var = (
with deleted as (
select * from old table (delete from my_table where foo > 1)
)
select * from new table (insert into archive_table select * from deleted)
);
However, this fails because a common table expression is not allowed within such a statement.
Is there any way to do this within a stored procedure?
(The task can be done using some other method as a work-around. But I want to find out if it is possible to do it this way. If this is not possible, it seems like quite a dumb restriction.)
Update: I'm using DB2 9.7 LUW.
If you issue a select, you have to consume the result set somehow, whether it is in a procedure or another application. You can either run a dummy loop within the procedure, like:
for t in (with deleted as (
select * from old table (delete from my_table where foo > 1)
)
select * from new table (insert into archive_table select * from deleted)
) loop
null;
end loop;
or use an explicit cursor:
declare c1 cursor for with deleted as (
select * from old table (delete from my_table where foo > 1)
)
select * from new table (insert into archive_table select * from deleted);
...
open c1;
close c1;
Note that neither of these is tested.
Why dont you flip it around? You can INSERT from a SELECT, and you can SELECT the rows from a DELETE.
I want to run a trigger when I update a certain field on the database, so it updates another field (basically we have 2 different unique IDs for each record, so when one is changed, we need to update the other too - yay!)
CREATE OR REPLACE TRIGGER trigger_name ON table AFTER
UPDATE AS
UPDATE table A
SET unique_to_update = NVL(
(SELECT b.unique_to_update_from
FROM table b
WHERE B.other_unique_id = A.unique_id_to_match
), 0);
I have no idea if this works (scared to test it, quite frankly, since I'm certain it'll break things) and even if it did, it'd run on every single update of that table - not just the one field that I wanted.
Any help would be much appreciated, thank you!
Test anything before putting it in production.
Something like this shoud be your trigger:
CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE of unique_id_to_match
ON table
FOR EACH ROW
AS
BEGIN
select
NVL(
(SELECT b.unique_to_update_from
FROM table b
WHERE B.other_unique_id = :new.unique_id_to_match
), 0)
into :new.unique_to_update
FROM dual;
END;
5000 rows x 900 columns is not so big :)
I was afraid it has 10M of rows :)
OK start
create temporary table tmp_my_important_columns on commit delete rows
as
select unique_id_to_match, unique_to_update_from,
other_unique_id , unique_to_update
from table where rownum < 1;
second
CREATE OR REPLACE TRIGGER trigger_before_upd_stmt
BEFORE UPDATE
ON table
AS
BEGIN
insert into
tmp_my_important_columns
select unique_id_to_match, unique_to_update_from,
other_unique_id , unique_to_update
from table;
END;
third,
CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE of unique_id_to_match
ON table
FOR EACH ROW
AS
BEGIN
select
NVL(
(SELECT b.unique_to_update_from
FROM tmp_my_important_columns b
WHERE B.other_unique_id = :new.unique_id_to_match
), 0)
into :new.unique_to_update
FROM dual;
END;
Comments:
After an update, if you update the same rows again, without commit
(which deletes the tmp table), you'll get problems. So, or you commit
after update, or you can add an after update trigger(without for each row) that deletes all, from tmp table, but this is somehow ugly.
You can add indexes on the temporary table.