How to insert a column value to only first thousand rows - sql

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);

Related

Big query not supporting update statement on TEMP table?

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.

Values of the inserted row in a Trigger Oracle

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;`

PLSQL Variables

I'm new to programming and I was wonder how I would declare a variable I can use through out my code.
What I want to achieve is :
Myvariable = (select Column from table1 where column =1234 group by column);
select column from table2 where column in (myvariable);
select column from table3 where column in (myvariable);
and etc
Thanks in advance :)
If you're using PL/SQL Developer to access an Oracle database you can create a Test window (File - New - Test Window) with code similar to the following:
DECLARE
myVariable TABLE1.COLUMN%TYPE := 1234;
BEGIN
FOR aRow2 IN (SELECT COLUMN
FROM TABLE2
WHERE COLUMN = myVariable)
LOOP
DBMS_OUPUT.PUT_LINE('Do something with ''aRow2''');
END LOOP;
COMMIT;
FOR aRow3 IN (SELECT COLUMN
FROM TABLE3
WHERE COLUMN = myVariable)
LOOP
DBMS_OUPUT.PUT_LINE('Do something with ''aRow3''');
END LOOP;
COMMIT;
END;
You'll need to edit the above to do whatever you want with the rows from TABLE2 and TABLE3.
Best of luck.
this is not really a variable... you can write the sql like this
select column
from table2
where column in (select Column from table1 where column =1234 group by column);
You can use a temporary TEMPORARY TABLE bound to the current session:
DECLARE GLOBAL TEMPORARY TABLE temp
{
column INTEGER
}
ON COMMIT DELETE ROWS -- Specify PRESERVE ROWS if you want to keep them through commits
NOT LOGGED
ON ROLLBACK DELETE ROWS -- Remove this line if you want to keep rows when you rollback a transaction
You load the table:
insert into temp1 (select Column from table1 where column =1234 group by column)
Then you can use the data using generic code:
select column from table2 where column in (select column from temp1);
select column from table3 where column in (select column from temp1);

Insert value into a table and insert one extra column by PL./SQL

I am inserting values from a cursor to two tables. Table A and B
but B will have one for extra column in it with
QUERY
CREATE OR REPLACE PROCEDURE fast_proc (p_array_size IN PLS_INTEGER DEFAULT 100)
IS
TYPE ARRAY IS TABLE OF all_objects%ROWTYPE;
l_data ARRAY;
CURSOR c IS
SELECT col1 ,col2,col3
FROM dual;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO tableB LIMIT p_array_size ;
FORALL i IN 1..tableB .COUNT
INSERT INTO t2 VALUES tableB (i);
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE c;
END fast_proc;
But this is giving me error as Status column is not getting filled. How can I insert all the values from the cursor and then add status as harcoded 'A'.
I cannot add it in the query as the same cursor will be used to insert in Table A.
If you are trying to do a partial fetch in the cursor and insert it to the table and later going to add status to the table, why not do it at the same time?
CURSOR c IS
SELECT col1 ,col2,col3,'A'
FROM dual;
'A' is where the status column is coming.
And if you want to insert values only after the cursor fetch, then change your insert statement to something like this:
INSERT INTO t2(col1 ,col2,col3) VALUES tableB(i);
Specify the columns where insertion should take place, ie, leave the status column out of it.

How insert rows with max(order_field) + 1 transactionally in PostgreSQL

I need to insert in a PostgreSQL table a row with a column containing the max value + 1 for this same column on a subset of the rows of the table. That column is used to ordering the rows in that subset.
I´m trying to update the column value in an after insert trigger but I´m obtaining duplicate values for this column in different rows.
What´s the best way to do that avoiding duplicate values for the ordering column in the subset in a concurrent environment with a lot of inserts in a short time?
Thanks in advance
EDIT:
The subset is defined by another column of the same table: this column has the same value for all the related rows.
If that column is used only for ordering then use a sequence:
create table t (
column1 integer,
ordering_column serial
);
http://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-NUMERIC-TABLE
New transactional-safe answer:
To make it in a transactional-safe way you could use this trigger, which creates sequences for each different "set_id" value:
create or replace function calculate_index() returns trigger
as $$
declare my_indexer_name text;
begin
my_indexer_name = 'my_indexer_name_' || NEW.my_set_id;
if NOT EXISTS (SELECT * FROM pg_class WHERE relname = my_indexer_name)
then
execute 'create sequence ' || my_indexer_name;
end if;
select nextval(my_indexer_name) into NEW.my_index;
return new;
end
$$
language plpgsql;
CREATE TRIGGER my_indexer_trigger
BEFORE INSERT ON my_table FOR EACH ROW
EXECUTE PROCEDURE calculate_index();
Also you could create manually sequences named 'my_indexer_name_1', 'my_indexer_name_2', etc. if your set_id possible values are known beforehand, then you could eliminate the if-then from the trigger function above.
This was my initial and not transactional-safe answer:
I would create a new helper table let's call it set_indexes:
create table set_indexes( set_id integer, max_index integer );
each record has the set_id and the max index value of that set. e.g.:
set_id, max_index
1 53
2 12
3 43
in the trigger code you would:
select max_index + 1 from set_indexes where set_indexes.set_id = NEW.my_set_id
into NEW.my_index;
// Chek if the set_id is new:
if NEW.my_index is null then
insert into set_indexes( set_id, max_index) values (NEW.my_set_id, 1);
NEW.my_index = 0;
else
update set_indexes set max_index = NEW.my_index where set_indexes.set_id = NEW.my_set_id;
end if;