PL/SQL Record and Table Variables inchanged - oracle

I am new to Oracle PL/SQL and have been given some code I am being asked to modify. I have been looking through the oracle documentation and think I know what it is doing but would like to get a verification as to if my understanding is correct or not.
Here is the code:
TYPE array_rec_type IS RECORD (gla_sub tblName.id%type);
v_closes_sc array_rec_type;
TYPE v_sc_type is TABLE OF v_closes_sc%TYPE INDEX BY BINARY_INTEGER;
sc_array v_sc_type;
Here is what I believe is being declared here:
TYPE array_rec_type IS RECORD (gla_sub tblName.id%type);
It looks like a collection is being declared using the column type from the id column from the tblName table. Which could be a number or UUID, etc.
v_closes_sc array_rec_type;
A variable of the newly created type is being created
TYPE v_sc_type is TABLE OF v_closes_sc%TYPE INDEX BY BINARY_INTEGER;
A new type is being created using the collection (Record) previously created a template for the table. The table will have a single column of ID.
sc_array v_sc_type;
A new variable is being created to hold the new table variable.

A record is not a collection, so your explanation is slightly confused. From the docs (which you've probably already looked at:
In a collection, the internal components always have the same data type, and are called elements. ... To create a collection variable, you either define a collection type and then create a variable of that type or use %TYPE.
In a record, the internal components can have different data types, and are called fields. You can access each field of a record variable by its name ... To create a record variable, you either define a RECORD type and then create a variable of that type or use %ROWTYPE or %TYPE.
So looking at what you said:
Here is what I believe is being declared here:
TYPE array_rec_type IS RECORD (gla_sub tblName.id%type);
This is a record, not a collection. In this case it has a single field called gla_sub which is indeed being declared using the data type of the id column from the tblName table. The use of %type means that, to some extent, you don't need to know what the data type actually is, and you may not have to change your code if that changes (if the size of a varchar2 column is increased, for instance).
v_closes_sc array_rec_type;
Correct - a variable of the newly created type is being created.
TYPE v_sc_type is TABLE OF v_closes_sc%TYPE INDEX BY BINARY_INTEGER;
This is a collection, specifically an associative array. It's a sparse array whose members are instance of the record type declared above, with a numeric index. That could also be declared using the type directly, as:
TYPE v_sc_type is TABLE OF array_rec_type INDEX BY BINARY_INTEGER;
sc_array v_sc_type;
Correct - a new variable is being created of that just-declared table type.
Having a record type with a single field seems a bit pointless, as you could have a collection based on the table column data type. Your existing code will be expecting that structure though, so changing it isn't quite trivial.

Related

How to give a field of an object the same type as a column of a table?

I would like to a object with a field that has the same type as column of a table.
create table TA (
TA_1 number
);
CREATE TYPE my_obj2 IS object
(
TA_1 TA.TA_1%type
);
ORA-24344: success with compilation error
Is it possible. If yes, what is wrong in this code?
code
You can't do that.
The CREATE TYPE document states:
This data type must be stored in the database; that is, either a predefined data type or a user-defined standalone collection type.

Informatica: Representing An Empty Column in Source Qualifier

I have a requirement to use a sql override query in source qualifier. The override query has an empty port (column) that is supposed to be populated in the database using a store procedure. How do I represent ( create ) the empty port(column) in the source qualifier?
Just create ports that reflect columns returned by the SQL override. Empty column may still have a name.

Oracle PL/SQL table of parent object type breaks when I add another inheriting child object type

I am using custom object types with Oracle PL/SQL, including several object types that inherit from a parent object. I have a TP_DOCUMENTS parent object, and child document types, such as TP_PUBLICATION, TP_CONTRACT, etc. We successfully created a table of TP_DOCUMENT and have added records of TP_PUBLICATION, TP_CONTRACT, and other child document records. However, I needed to create an additional type of document. Once I did this, it broke the DOCUMENTS table. How can I create additional child types, without breaking the table of the parent object (making me lose all the data previously contained in the parent object table!!)?
Here is some of my code:
create or replace TYPE "TP_DOCUMENT" AS OBJECT
(
...fields go here
) NOT FINAL
create or replace TYPE "TP_PUB_INSTRUCTION" UNDER TP_DOCUMENT()
CREATE TABLE DOCUMENTS OF TP_DOCUMENT
After creating these types (and others with additional fields), I created the table DOCUMENTs as shown above. I tried to create another sub-type, and the DOCUMENTS table broke.
MORE INFORMATION:
The error code message is as follows:
ORA-04063: table/view has errors
Cause: Attempt to execute a stored procedure or use a view that has errors. For stored procedures, the problem could be syntax errors or references to other, non-existent procedures. For views, the problem could be a reference in the view's defining query to a non-existent table. Can also be a table which has references to non-existent or inaccessible types.
Action: Fix the errors and/or create referenced objects as necessary.
Thank you!
UPDATE WITH ANSWER FROM COMMENTER BELOW:
I had unfortunately dropped a Sub-Type using the Force option. That likely was the cause for why my Documents table was corrupted. In the future, I will use the Validate command (see answer below).
Instead of FORCE you should use the VALIDATE option when dropping types:
VALIDATE
If you specify VALIDATE when dropping a type, then Oracle Database
checks for stored instances of this type within substitutable columns
of any of its supertypes. If no such instances are found, then the
database completes the drop operation.
This clause is meaningful only for subtypes. Oracle recommends the use
of this option to safely drop subtypes that do not have any explicit
type or table dependencies.
Here's an example:
create or replace type tp_document as object
(
a number
) not final;
create or replace type tp_pub_instruction under tp_document();
create table documents of tp_document;
--This fails with this error message:
--ORA-02303: cannot drop or replace a type with type or table dependents
drop type tp_pub_instruction;
--This works since there's no data with that type.
drop type tp_pub_instruction validate;

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

Resources