retrieve user defined datatype from table - oracle

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.

Related

Updating Resultset that points to an Oracle view

Is it possible to do updates via Resultset to an Oracle view? Asking as my code is giving me insufficient priviledge error when it does the rs.updateRow() call. I have checked and I definitely have access to the table/view.
The code looks like:
white (rs.next()) {
int updateStatus = getPSCforAction(status);
rs.updateInt("SPSC", updateStatus);
rs.updateRow;
}
The SELECT statement changes depends on operation but it will always be querying an Oracle view (and in some cases multiple views). My main question is whether updating via resultSet can be done to an Oracle view (or views)?
To answer your question one must see a definition of you view and a SELECT statament that is used to produce the resulset in your Java code. Without looking at this it is hard to give the answer
Anyway, generar rules and limitations are described in the Oracle Database JDBC Developer's guide:
Result Set Limitations
The following limitations are placed on queries for enhanced result
sets. Failure to follow these guidelines results in the JDBC driver
choosing an alternative result set type or concurrency type.
To produce an updatable result set:
A query can select from only a single table and cannot contain any
join operations.
In addition, for inserts to be feasible, the query must select all
non-nullable columns and all columns that do not have a default value.
A query cannot use SELECT * . However, there is a workaround for this.
A query must select table columns only.
It cannot select derived columns or aggregates, such as the SUM or MAX
of a set of columns.
To produce a scroll-sensitive result set:
A query cannot use SELECT *. However, there is a workaround for this.
A query can select from only a single table.
Scrollable and updatable result sets cannot have any column as Stream.
When the server has to fetch a Stream column, it reduces the fetch
size to one and blocks all columns following the Stream column until
the Stream column is read. As a result, columns cannot be fetched in
bulk and scrolled through.
They vaguely write that:
A query can select from only a single table and cannot contain any
join operations.
Could be that they mean "exlusively from tables, but not views", but also they could mean: "from tables and views", nobody knows, one must test this.
Another possible problem - your view may not be updatable, that is it doesn't conform to the following rules:
Notes on Updatable Views The following notes apply to updatable views:
An updatable view is one you can use to insert, update, or delete base
table rows. You can create a view to be inherently updatable, or you
can create an INSTEAD OF trigger on any view to make it updatable.
To learn whether and in what ways the columns of an inherently
updatable view can be modified, query the USER_UPDATABLE_COLUMNS data
dictionary view. The information displayed by this view is meaningful
only for inherently updatable views. For a view to be inherently
updatable, the following conditions must be met:
Each column in the view must map to a column of a single table. For
example, if a view column maps to the output of a TABLE clause (an
unnested collection), then the view is not inherently updatable.
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY Joins, with some exceptions, as
documented in Oracle Database Administrator's Guide
In addition, if an
inherently updatable view contains pseudocolumns or expressions, then
you cannot update base table rows with an UPDATE statement that refers
to any of these pseudocolumns or expressions.
If you want a join view to be updatable, then all of the following
conditions must be true:
The DML statement must affect only one table underlying the join.
For an INSERT statement, the view must not be created WITH CHECK
OPTION, and all columns into which values are inserted must come from
a key-preserved table. A key-preserved table is one for which every
primary key or unique key value in the base table is also unique in
the join view.
For an UPDATE statement, the view must not be created WITH CHECK
OPTION, and all columns updated must be extracted from a key-preserved
table.
For a DELETE statement, if the join results in more than one
key-preserved table, then Oracle Database deletes from the first table
named in the FROM clause, whether or not the view was created WITH
CHECK OPTION.

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.

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.

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