We have an Oracle 11g database table with around 35 million rows. We are in a situation where we have to update all values of one column. This column is indexed.
I have a script that can generate the updated values and can populate it in a text file.
I'm looking for a good strategy to do a bulk update to this table. We can afford a downtime of around 10 hours.
Will it be a good idea to
Dump the entire table to a flat file
Update the values using any scripting language
Reload the entire table
Rebuild indexes
What are the pitfalls that one can encounter?
I'm not competent in PL/SQL. Is there a way to solve this in PL/SQL or any way "within" the database itself?
Thanks,
Prabhu
The fastest way will probably be to create an external table based on your flat file of update values and then:
create table new_table as
select o.col1, o.col2, o.col3, ..., x.value as colN
from old_table o
join extern_table x on ...;
(Make sure that join returns all the rows from old_table. The join may need to be an outer join.)
-- drop foreign key constraints that reference old_table
alter table child1 drop constraint fk_to_old_table1;
...
drop table old_table;
rename new_table to old_table;
-- Re-create indexes and constraints on old_table
alter table old_table add constraint oldpk primary key (col1);
...
-- Re-create the dropped foreign key constraints to old_table
alter table child1 add constraint fk_to_old_table1 ...;
...
Related
How to Enable/Disable Indexes in TERADATA Database?
I want to disable indexes and do update and then enable the indexes in Teradata.
If Enable/Disable option not available in Teradata, in the sense How can I achieve this ? If I use DROP Indexes, how can I recreate the indexes for all the tables?
Teradata gives you a way to create a table without choosing for primary index (if you are sure of any column).
You can create table with No primary Index. Here is a sample of how to do so:
Create table <table name>
(<columnname> <datatype>,
<columnname> <datatype>)
no primary index ;
Teradata does not have a disable index feature.
All tables have a Primary Index (PI) which is chosen by the RDBMS unless you specify one.
CREATE INDEX <index name> (<column list>) ON table name;
CREATE UNIQUE INDEX (department) ON tbl_employee;
DROP INDEX ind_dept ON tbl_employee;
DROP INDEX (department,emp_number) ON tbl_employee;
In Teradata you can't drop Primary index of a table. The primary index defines where data will reside and which AMP receives the row.
To alter the primary index of a table you need to delete all the records from the table ( As data is already distributed by the row hash value of the PI) then only you can change the primary index of a table by using below command:-
Alter table table_name modify primary index index_name (column list);
Steps to achieve your goal
You can crate a new table with your desired index ( temp, wrk, intermediate table) insert the records from the original table and update the wrk table.
delete the original table and insert the wrk table data.
And you are done.
Create & Drop index is the only option you have here
Simple answer - you can't disable and re-enable indexes in Teradata.
However, there some workarounds.
Drop Index
If you talking about PI (primary index) - you can't drop it. All you can do is to make a copy of a table without an index.
You can drop secondary index though. Then simply create it again when you need it.
Drop-Create Table
This doesn't fit all cases, but often this is the fastest way to do the work, especially if the issue you have is with PI.
BTW: it is not clear, why would you need to do that? Performance or logic or something else? That probably will affect recommendation.
Since you did not specify what kind of index you want to disable/enable, below are the approach you can follow on either cases.
PRIMARY INDEX
CREATE a new table with the same PI
INSERT the updated data to new table
DROP the old table - DROP TABLE <OldTable>;
RENAME the new table same as the old one. - RENAME TABLE <NewTable> TO <OldTable>;
Above recommendation for Primary Index is only applicable if you are going to update a primary index column value. If you will update other columns (not the PI column) then you can just issue an UPDATE Statement directly.
SECONDARY INDEX
DROP the SI - DROP INDEX <IndexName> ON <TableName>;
UPDATE table data
RECREATE the SI - CREATE INDEX <IndexName> (<ColumnList>) ON <TableName>;
I'm coming from SQL Server enviroment where you can declare a temp table with #table, but as I've read you can't do this in oracle.
I want get a value for 500.000 hardcoded id's from a table, but as the IN clause has a limit of 1000 I need to find another way. Is the best way to create a temporary table and insert the hardcoded values and then join the other table which contains the values I need ?
My client (toad) has autocommit set to off and I dont want to commit anything, I want it to be session-based so when I close the database client I want the temporary table do disappear. Is the code below the right way to do in oracle?
CREATE GLOBAL TEMPORARY TABLE Test(HardcodedId number(10))
ON COMMIT DELETE ROWS;
I've also tried to use inner join and in the join select the hardcoded values from dual, but this creates a column for each value and i'm not able to use a reference to join with. Is it possible to insert all values into a single column in dual?
You can use some thing like this (500 union all)
select * from (
select '1' from dual
union all
select '2' from dual
...) q
Then you can join this with other tables.
For your situation, I would use a GTT (global temporary table) - which you have already researched by the looks.
The advantage of a GTT is that it's a permanent object (so no need to constantly create and drop it) and the data "stored" in it is on a session basis.
I needed to delete a column from a table that other tables had a foreign constraint on. I guess ALTER TABLE doesn't let you remove columns, so I had to create a new table without the column and copy the data over and rename them appropriately. Though now it won't let me delete the old table with the extra column because of foreign table constraints still I guess pointing to the old table instead of the new one... even though the new one now has the correct name. What is the recommended practice for making the foreign keys point to the right table now that I did the switch?
I don't think that you can. You might have to recreate all the other tables with the updated foreign key, because you cannot change foreign key constraint conditions or at least as far as I know.
I've created a second table that I want to copy data from a first table to.
table2 has the same structure as table1, only some of it's columns are COLLATE NOCASE. Apart from that and the table names, the tables are identical.
Each table has the PK:
hID INTEGER PRIMARY KEY AUTOINCREMENT
When copying, I get an error on the following query:
INSERT INTO table2 SELECT * FROM table1
The error:
PRIMARY KEY must be unique
I'm assuming the original data is unique, as it's always had the PK.
I want to preserve the original hID's when copying ie I don't want new hID's set for the old data being copied.
In MySQL, I'd normally apply a PK to the second table AFTER copying over the data, but I think that's not allowed in SQLLite.
Can anyone explain the error in my ways?
i have the following problem. I have three tables, TABLE_1, TABLE_2 and TABLE_3.
Between TABLE_1 and TABLE_2 is a m:n relationship so theres a connecting table
lets call it TABLE_1_2.
Between TABLE_2 and TABLE_3 is a m:n relationship so theres a connecting table
lets call it TABLE_2_3.
If i delete now a row from TABLE_1 i want that all rows from the other tables connecte also will be deleted.
How can i handle this? i read that sqlite doesnt supports joins for delete statements.
In MS SQL this can be made via altering the table1 and corresponding column by adding ON DELETE CASCADE CONSTRAINT on this column. But in SQLite there is no ALTER COLUMN and ALTER TABLE is also much less functional than in MS SQL. That's why you'll probably have to
Rename the table1 to a table3
Create a new table with ON DELETE CASCADE CONSTRAINT and all other constraints you've already used.
Copy the content of the old table to the new one.
Remove the old table
See also the similar topic.