Oracle PLSQL Alter/Drop Attributes of Object Type - oracle

I am new to Oracle PLSQL and have to Alter an Object Type. I´ve made many mistakes with the data types of the new Columns, so I had to drop them and altered them a second time.
For example, I did this:
ALTER TYPE testObjectType ADD ATTRIBUTE (Prename VARCHAR2(50))
ALTER TYPE testObjectType DROP ATTRIBUTE Prename
ALTER TYPE testObjectType ADD ATTRIBUTE (Prename VARCHAR2(50 CHAR))
Now below the "Create or Replace" - Code of the Object there are many lines of code about adding & dropping Attributes. I´ve to try to simply delete this lines but the changes don't work at all. How can I tidy up my Object-Type? (I'm using Oracle SQL Developer).

You need to reset it so it is no longer treated as an evolved type:
alter type testobjecttype reset;
Then you can rebuild it with:
create or replace type testobjecttype as object
( prename varchar2(50 char) );
(plus any other attributes etc it should have).
btw there isn't much point naming database objects in CamelCase as the database ignores it, and schema browsers will just list it in uppercase (because that's how the dictionary stores names), which can become hard to read without word separators. (And shouldn't it be TestObjectType anyway?) There is a better case for it in naming program variables, although they are case-insensitive as well, so it's probably simplest and cleanest to just code in lowercase.

Related

Why can't we drop a referenced Type unlike other schema objects

When a Type which is having dependents is tried to drop or replace, oracle throws below error. Unlike for the other schema objects (like procedures) where you drop an objects then it gets dropped and the dependent objects get invalid. My two questions are
1) Why is Typeso special that it prevents drop/replace when it has dependents.
2) What logic takes separates the above behavior for Type.
create
ORA-02303: cannot drop or replace a type with type or table dependents.
"Why is Type so special "
There are two differences between Types and Procedures.
Sub-types have an absolute dependency on their super-type. If a stored procedure has a dependency on a function and we delete that function the procedure is invalidated. But we can make the procedure valid simply by editing the code so it doesn't use the function. Whereas if we drop the super-type the sub-type is permanently invalidated; we cannot edit it to remove its dependence on the super-type, because the super-type defines it. Simply, the sub-type is inoperable until we re-create the super-type.
We can use a Type to declare database tables and table columns. Those are structures with persistent state: we can't invalidate a table column like a stored procedure, because of the data. If we drop a Type which is used by a database table we lose the data held in the Type structure.
There is syntax to drop a Type with dependencies without hurling ORA-02303:
drop type my_type force;
This renders all the sub-types invalid, and - more drastically - sets any dependent table columns as unused and invalidates any dependent tables. An unused table column is effectively dropped; its data is inaccessible. To recover an unused column (or invalidated table) requires a tablespace point-in-time recovery on an auxilliary instance, which is not a trivial undertaking. (That it is so easy to unwittingly render data irretrievable is one reason why object-relational tables are not a good idea.)

Table types with dba objects

Why can't we create an object with the below code.
create or replace type typ_obj_dba_test as object (name_col
dba_objects.object_name%type);
It gives me object_name must be declared.
Is it because dba_objects is a view?
"Is it because dba_objects is a view?"
No. You couldn't do it with a table column either. The %TYPE syntax is restricted to PL/SQL and you are creating a SQL TYPE, not PL/SQL.
This restriction is annoying to many developers, particularly those coming from a background in more dynamic programming languages. But the snag is %TYPE syntax is dynamic: if the referenced column changes its data type the referencing object changes.
That's neat when we're declaring variables or parameters in stored procedures. But we can use SQL types to define table columns (*). Cascading a change in one column to who-knows-how-many columns which reference it would be a nightmare. So Oracle doesn't allow us to do it.
I'm afraid you'll need to use an explicit datatype declaration:
create or replace type typ_obj_dba_test as object (
name_col varchar2(30)
);
(*) It's not generally advisable to use Types in table definitions, but Oracle supports ORDBMS data structures.

Oracle check constraint for varray type

I have a custom type defined as this :
CREATE TYPE myType_t AS VARRAY(2) of char(10);
Is it possible to add a check constraint on the char(10) type, so myType_t items respect a certain regex? I tried things like
CREATE TYPE myType_t AS VARRAY(2) of char(10)
( constraint c_myType_format check ( regexp_like(IdontKnowWhatToWriteHere, '[:digit:]{8}'));
which obviously doesn't work... I thought maybe defining another type for the
AS VARRAY(2) of myOtherType_t
but here again I don't know where to put the regex check.
And yes, I also tried adding the constraint to the table that will use my type, but I can't find the correct syntax.
According to Oracle documentation:
Oracle does not support constraints on columns or attributes whose
type is a user-defined object, nested table, VARRAY, REF, or LOB

Can I drop/add attribute without consequences? Oracle Object Type

I have an OBJECT_TYPE with ATTRIBUTE varchar2(200). There many other objects referencing this one. I need to reduce the length of the attribute to varchar2(50). I know I cannot do it directly, so I found this way:
ALTER TYPE CUSTOMER DROP ATTRIBUTE name INVALIDATE;
ALTER TYPE CUSTOMER ADD ATTRIBUTE name varchar2(50) CASCADE;
The question is: is there anything that could be broken after the dropping/creating of the attribute? Is it correct to use the INVALIDATE option instead of CASCADE in the DROP statement? I don't want to loose anything - relations or data.
Is there a reason the following is not used:
ALTER TYPE CUSTOMER MODIFY ATTRIBUTE name VARCHAR2(50);
I have run into compatibility problems when using types and dropping an attribute especially if there are tables and data defined using the types. This is one reason I avoid basing tables and views on the data types. The change in the length would invalidate the table and any rows where the associated data exceeds 50. If the other objects are just types and are not used in views and tables then the alter type above should work fine. And you may need to recompile any types. Keep in mind that the type is becoming more restrictive and how it may affect any associated data.

How do I rename a table in Oracle so that all foreign keys, constraints, triggers and sequences are updated and any existing data is preserved?

I need to rename a table in Oracle but I want to be sure that any foreign keys, constraints, triggers and sequences that reference the table are updated to use the new name.
How can I be sure that I have not broken anything?
Note that I want to preserve any existing data that the table contains.
If you
ALTER TABLE old_table_name
RENAME TO new_table_name;
all the existing constraints (foreign key and other constraints) and triggers will reference the newly renamed object. Sequences have no relationship to tables so there will be no impact on the sequences (though if you mean that you are referencing the sequence in a trigger on the table, the trigger will continue to reference the same sequence after the rename). Any stored procedures that you have written that reference the old table name, however, will need to be updated to reference the new table name.
Now, while the constraints and triggers will continue to work correctly, they will retain their original names. If you have naming conventions for these objects that you want to maintain after the table name, you'd need to do more. For example, if you want a row-level before insert trigger on table FOO to be named TRG_BI_FOO and you rename the table to BAR, you'd need to alter the trigger explicitly to change its name
ALTER TRIGGER trg_bi_foo
RENAME TO trg_bi_bar;
Similarly, you'd need to rename your constraints and indexes
ALTER TABLE bar
RENAME CONSTRAINT pk_foo TO pk_bar;
It depends on what you mean by "any foreign keys, constraints, triggers and sequences that reference the table are updated to use the new name."
Any existing indexes, constraints, and triggers against the table being renamed will automatically reference the new name.
However, any naming conventions used for those objects won't automatically use the updated name. For example, if the primary key for TABLE_NAME is generally named TABLE_NAME_PK, renaming TABLE_NAME to NEW_TABLE_NAME won't automatically rename the primary key constraint to NEW_TABLE_NAME_PK.
What will need to be checked is code - packages, procedures, and functions - which referenced the old table name, as well as any triggers which referenced the old table name. Similarly, views against the old table name will break as well. The view ALL_DEPENDENCIES can help identify which of those objects need to be updated.
ALTER TABLE oldName RENAME TO newName
Will preserve the table's dependencies and data but there can always be a piece of PL/SQL that references the old name which is going to become invalid.

Resources