Table types with dba objects - oracle

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.

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

Oracle PLSQL Alter/Drop Attributes of Object Type

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.

retrieve user defined datatype from table

SQL> -- CASE 1
SQL>select nest_test.id.num from nest_test;
select nest_test.id.num from nest_test
*
ERROR at line 1:
ORA-00904: "NEST_TEST"."ID"."NUM": invalid identifier
SQL> -- CASE 2
SQL>select n.id.num from nest_test n;
ID.NUM
----------
12
As, AFAIK, aliasing any table is just giving simple name to the table or column. Then, why I'm getting error in Case 1, when I'm trying to retrieve user defined object from table ? What actually happened, when I aliased my table.
The Oracle documentation states that table aliases are required to reference methods or attributes of objects to avoid the potential for "inner capture" (a table column name clashing with an object attribute name). Find out more.
The documentation states:
"You must qualify a reference to an object attribute or method with a table alias rather than a table name even if the table name is itself qualified by a schema name."
It doesn't say why Oracle enforce this rule. But there is obviously some complexity in the namespace implementation, caused by retrofitting objects into the relational kernel.
"then, why this query works select emp.sal from emp"
Because that's a regular column on a table. Oracle have never enforced aliases on normal tables. Starting now would break an enormous amount of code which has accrued over the decades.
Having to use aliases is just one more penalty for using object types to define table columns. It's far from being teh most onerous aspect of the clunky syntax which goes with Oracle's ORDBMS implementation.
Besides, there's almost cases in which using objects rather than realtional tables to persist data is the rigyht solution, so it doesn't really matter.

Difference between object and record type

I am just curious whats the difference between object and record type in oracle, More specifically between the below declarations
create type emp2_oty is object
(
empno number,
ename varchar2(20),
deptno number
);
create type emp2_nt is table of emp2_oty;
and
type emp2_oty is record
(
empno number,
ename varchar2(20),
deptno number
);
create type emp2_nt is table of emp2_oty;
Please elaborate.
record:
Cannot be stored in the database.
Cannot be recursively referenced.
Cannot have logic defined as part of their definition.
object:
Can be stored as a database table column or as an entire row.
Can be recursively referenced using the SELF parameter.
Can have logic defined as part of their definition using member methods.
The OBJECT type can be stored in the database and can be used in both SQL and PL/SQL
Understanding PL/SQL Records
Records are composed of a group of fields, similar to the columns in a row.The %ROWTYPE attribute lets you declare a PL/SQL record that represents a row in a database table, without listing all the columns.
Basically, if you are familiar with C/C++ or similar languages, you could tell that Records are nothing but structures (i.e a data type that can be used to group items of possibly different types into a single type) they can not have methods within. Objects on the other hand are completely different:
Oracle Objects
Oracle object types are user-defined types that make it possible to model real-world entities
1. Objects Can Encapsulate Operations Along with Data
Database tables contain only data. Objects can include the ability to perform operations (i.e methods) that are likely to be needed on that data (e.g a purchase order object might include a method to sum the cost of all the items purchased).
2. Objects Can Represent Part-Whole Relationships
An object can have other objects as attributes, and the attribute objects can have their own object attributes too. An entire parts-list hierarchy can be built up in this way from interlocking object types.
3. Objects Are Efficient
3.1 Object types and their methods are stored with the data in the database, so they are available for any application to use.
3.2 You can fetch and manipulate a set of related objects as a single unit (e.g when you select a customer object and get the customer's name, phone, and the multiple parts of his address in a single round-trip between the client and the server) .

Find references to specific column in Oracle in Jobs and Procedures

I'm looking for a query allowing me to query all the tables, views, JOBS, and PROCEDURES in the oracle database. I've found some links to queries that will work for the tables and views but I need jobs and procedures. If one query can't be used for all this, I need at least job and procedures.
Here is what I found for the tables and views:
Select TABLE_NAME, COLUMN_NAME from user_tab_columns
TIA
My guess is that you want something like
SELECT name, type, line, text
FROM user_source
WHERE lower(text) like lower('%<<column name>>%');
That will show you any line of code in any pL/SQL object (package, package body, procedure, function, trigger, type, etc.) that contains the column name. If there are multiple tables with identically named columns (i.e. a column name is found in many different tables), all instances will be identified. There isn't a really great way, short of inspecting the code, to figure out which queries refer the name column in one particular table. You could potentially look to see whether the NAME and TYPE from USER_SOURCE appear in DBA_DEPENDENCIES as referencing the particular table you're interested in. But that just shows you table-level dependencies at an object level and your object may depend on a large number of different tables.

Resources