I'm finding the solution to declare INDEX clause without using/bind with any variable in MIB table.
Generally when declare INDEX clause I use 1 variable as index
e.g.
dataEntry OBJECT-TYPE
SYNTAX dataEntry
ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"The entry of data Table"
INDEX { dataIndex }
::= { dataTable 1 }
dataEntry ::= SEQUENCE {
dataIndex
INTEGER,
dataValue
INTEGER
}
dataIndex OBJECT-TYPE
SYNTAX INTEGER
ACCESS read-only
STATUS mandatory
DESCRIPTION
"The index of data table"
::= { dataEntry 1 }
dataValue OBJECT-TYPE
.
.
but what I want is use dataIndex in INDEX clause but will not declare it in SEQUENCE and variable. something right this
dataEntry OBJECT-TYPE
SYNTAX dataEntry
ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"The entry of data Table"
INDEX { dataIndex }
::= { dataTable 1 }
dataEntry ::= SEQUENCE {
dataValue
INTEGER
}
dataValue OBJECT-TYPE
.
.
What I wrote is compiled error for sure, but is it have possible solution for what I want?
Instead of reinventing the wheel please consider learning the following parts of SMI standards:
Augmented Table: Augmented Table comes in to picture when there is one-to-one dependency between rows of one table and rows in another table. Wherein one table is the base and the other augmenting table. This might arise when a particular MIB imports another MIB and shares the same table (A classic example is If-MIB imports the group interfaces defined in RFC1213-MIB, where IF-MIB augments the ifTable defined in RFC1213-MIB)
Tables with External index:
These tables are similar to the augmented tables which shares the index values with other tables except that these are SMIv1 tables and the augmented tables are SMIv2 tables.
Related
As the title said : I want to create a type in oracle based on an existing Table.
I did as follow :
create or replace type MY_NEW_TYPE as object( one_row EXISTING_TABLE%rowtype);
The Aim is to be able to use this into a function which will return a table containing sample row of the table EXISTING_TABLE :
create or replace function OUTPUT_FCT() return MY_NEW_TYPE AS
...
If you only need to create a function that returns a row from your table, you could try something like the following, without creating types.
setup:
create table EXISTING_TABLE( a number, b varchar2(100));
insert into EXISTING_TABLE values (1, 'one');
function:
create or replace function OUTPUT_FCT return EXISTING_TABLE%rowtype AS
retVal EXISTING_TABLE%rowType;
begin
select *
into retVal
from EXISTING_TABLE
where rownum = 1;
--
return retVal;
end;
function call
SQL> begin
2 dbms_output.put_line(OUTPUT_FCT().a);
3 dbms_output.put_line(OUTPUT_FCT().b);
4 end;
5 /
1
one
However, I would not recommend such an approach, because things like select * can be really dangerous; I would much prefer defining a type with the fields I need, and then explicitly query my table for the needed columns.
No, you can't do that, you'll get a compilation error:
create or replace type my_new_type as object(one_row t42%rowtype);
/
Type MY_NEW_TYPE compiled
Errors: check compiler log
show errors
Errors for TYPE STACKOVERFLOW.MY_NEW_TYPE:
LINE/COL ERROR
-------- -----------------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
1/36 PLS-00329: schema-level type has illegal reference to MYSCHEMA.T42
You will need to specify each field in the object type, and you will have to specify the data types manually too - you can't use table.column%type either.
You could create the type dynamically based on column and data type information from the data dictionary, but as this will (hopefully) be a one-off task and not something you'd do at runtime, that doesn't really seem worth it.
You can create a PL/SQL table type based on your table's rowtype, but you would only be able to call a function returning that from PL/SQL, not from plain SQL - so you couldn't use it in a table collection expression for example. If you were only returning a single sample row you could return a record rather than a table, but the same applies. You can also have a function that returns a ref cursor which could match the table's structure, but you wouldn't be able to treat that as a table either.
Read more about object type creation in the documentation. Specifically the attribute and datatype sections.
I am trying to create an oracle table of oracle-object type.
Here is how my object structure looks like
CREATE OR REPLACE TYPE PERS_T AS OBJECT
(
empno number(4)
, ename varchar2(10)
, job varchar2(9)
, hiredate DATE
, sal number(7,2)
, comm number(7,2)
, deptno number(2)
)NOT FINAL;
CREATE OR REPLACE TYPE EMP_T FORCE UNDER pers_t (
mgr pers_t
);
All these are fine, but what when I am trying to create a table of EMP_T type using
CREATE TABLE table_name(emp_type EMP_T);
I am getting error
SQL Error: ORA-30756: cannot create column or table of type that contains a supertype attribute
Is it possible in oracle to create table like this?
I don't think so. According to Oracle's own support database, the following applies to a ora-30756
Error Text, Cause and Action from Message File/s for ORA-30756
Versions 9.2, 10.1, 10.2, 11.1, 11.2, 12.1
Error: ORA-30756 cannot create column or table of type that contains a supertype attribute
Cause: The user tried to create a column or table of an object type that
contains a supertype attribute. This is not supported because it leads
to infinite recursion in our current storage model. Note that creating
a column of a type implies that we create columns corresponding to all
subtype attributes as well.
Action: Change the type definition to contain a supertype REF attribute
instead of the supertype object attribute.
You have created a super type PERS_T so I believe this is your problem. As the article states, you can create a reference attribute instead of an object attribute as a work around as #tbone explained - CREATE TABLE table_name(emp_type REF EMP_T);
You are not permitted to sub-type an IS-A relationship using the UNDER keyword simultaneously with a HAS-A relationship using the same type. This ultimately translates to creating an object that refers to itself and it would lead to infinite recursion. You can instead have a pointer to the object of the same type within your code using REF as follows:
CREATE OR REPLACE TYPE EMP_T UNDER PERS_T (
mgr REF PERS_T
);
create table table_name(emp_type emp_t);
desc table_name;
Name Null Type
-------- ---- -------
EMP_TYPE EMP_T()
IS-A and HAS-A relationships in Oracle type inheritance
IS-A and HAS-A relationships both enable polymorphism and reusability of code but they define fundamentally different relationships between two types.
IS-A
The UNDER keyword is intended to sub-type relationships using the IS-A inheritance model. For example, employee IS-A person who has an emp_id as defined using:
create type person_type as object(ssn number, address varchar2(100)) NOT FINAL;
-- Employee is a **person** with an emp_id.
create type employee_type under person_type(emp_id number)
The idea is that an object of employee_type is also an object of person_type but with the additional specification of the emp_id. This lets for the inheritance model of polymorphism by enabling code reuse via extension of the person_type supertype. Note that it is always possible to define another extension of the person_type student as follows:
-- Student is a person with a student_id
create type student_type under person_type(student_id number)
HAS-A
As such, Oracle does not force upon us any keywords when attempting to create a composite sub-type. It is not syntactically inappropriate to define a sub-type containing one or more super-types as freely as other native types. For example, it is legal to define a composite sub-type classroom_type by composing it with a teacher of type person, 3 students each of type person as well as a room number of type number such as:
create type classroom_type as object ( teacher person_type,
student1 person_type,
student2 person_type,
student3 person_type,
room_number number)
The HAS-A relationship exists between two objects when one object belongs-to the other i.e. the former object consists of the latter.
However, this practice can cause unnecessary replication of large objects as you are copying the data from one place to another. To make things more efficient, akin to the concept of passing by reference in programming, the REF modifier lets you pass a pointer to an object for use in various scenarios including composite sub-types. Therefore, the above DDL of the class_type can be rewritten as:
create type class_type as object ( teacher ref person_type,
student1 ref person_type,
student2 ref person_type,
student3 ref person_type,
room_number number)
and is much more efficient. It is useful to note that changes to the referenced object will automatically be propagated downstream.
In the example in the question OP wishes to use both an IS-A relationship as well as a HAS-A relationship simultaneously such as in
An employee "is a" person "has a" manager (who "is a" person)
which is a fair translation of a real-world concept. However, to make it legal without leading to infinite recursion, we modify it as:
An employee "is a" person "has a" manager (who "is a" 'reference to' a person)
TL;DR
In PL\SQL, I need to return a collection type on which I can do a SELECT, but I cannot select from a table of record : PLS-00642: local collection types not allowed in SQL statements.
Long version
I have a table representing nodes of a graph and a table representing it's oriented arcs :
node_table(
node_id int,
data
)
arc_table(
source_node_id int,
destination_node_id int
)
In a package, I have a recursive algorithm representing a graph traversal. It returns all the possible nodes currently visited for a condition and a number of step. It presumes that we can start on any node. The pseudo-codes goes like this.
function getPossibleNodes(number_of_steps, condition):
returns node_collection_type
declare
previous_result node_collection_type
result node_collection_type
begin
if number_of_step = 0:
select node_id
bulk collect into result
from node_table;
else
previous_result = getPossibleNodes(number_of_steps - 1, condition);
select destination_node_id
bulk collect into result
from node_table join arc_table on
node_id = source_node_id
where *condition*
end id;
return result;
end;
The problematic is the format of the returned data. I wanted to return a table of record, declared in this way :
TYPE node_search IS RECORD (
ID INT,
error_count INT,
previous_error_count INT, -- for transposition
NODE_CHARACTER VARCHAR(1)
);
TYPE se_node_search_list IS TABLE OF node_search ;
However at the compilation I get : PLS-00642: local collection types not allowed in SQL statements.
I've been thinking of using a cursor, but looping on each line implies making a select to get the nodes accessible from the current node for each line. Plus, I'm not sure if I can populate another cursor to return for the current iteration in this way.
I tried declaring the record type in the current package and the table type as a global type, but then it cannot access the current type.
This function is executed to help with autocomplete at run time, so I have a strong execution-time constraint. The number of node however should not be higher than 5000.
What collection type can I return to get it to work ?
Try to define a schema level type and not plsql type. This error depicts that you are trying to access plsql type rather than SQL object. Hope tho helps.
CREATE OR REPLACE TYPE node_search IS OBJECT (
ID NUMBER,
error_count NUMBER,
previous_error_count NUMBER, -- for transposition
NODE_CHARACTER VARCHAR2(1)
);
CREATE OR REPLACE TYPE se_node_search_list IS TABLE OF node_search ;
I am having troubles when i want to create a named calculation from two different tables.
I have the table "CallesDim" with an id(PK) and a description and the table "UbicacionesDim" with an id (PK), another id (FK to "CallesDim") and a description:
--
CallesDim
id PK
Descripcion VARCHAR
--
UbicacionesDim
id PK
CalleId FK to id from CallesDIM
Altura INT
--
I want to concatenate "Descripcion" from "CallesDim" with Altura from "UbicacionesDim".
I try doing this:
CallesDim.Descripcion + ' ' + CONVERT(VARCHAR,UbicacionesDim.Altura)
but i am having the following error:
the multi-part identifier "CallesDim.Descripcion" could not be bound
Any ideas?
Thanks!
In a named calculation you can only access columns from the table that it is defined on.
Which record of the other table should it take in case it would accept columns from other tables? How should it join? All this cannot be configured.
If you need to join two (or more) tables, you can define a named query that can contain joins and access as many tables as you like. A named query can contain everything that you can state in a single select statement.
I'm studying databases and am currently working on a object-relational DB project and I've encountered a small problem with the number of possible constraints in an object table. I'm using "Database Systems: The Complete Book" by Hector Garcia-Molina (and other authors) as a reference and there's a general SQL example like this:
CREATE TYPE StarType AS (
name CHAR(30),
address AddressType,
bestMovie REF(MovieType) SCOPE Movies
);
Now, I have a kind of a similar type in my project, as it also uses reference to another type within a type, but the clause for placing a reference there doesn't include SCOPE in Oracle (at least I haven't found it in the docs and it outputs an error). So I have a type like this:
CREATE OR REPLACE TYPE "ApplicationType" AS OBJECT (
"person" REF "PersonType",
"competition" REF "CompetitionType",
"dateApplied" DATE
);
/
...which works. But when I want to constrain the REF columns, I can constrain only one, as so:
CREATE TABLE "Applications" OF "ApplicationType" (
"person" SCOPE IS "People" /* or "competition" SCOPE IS "Competitions" */
)
OBJECT IDENTIFIER IS SYSTEM GENERATED;
Is there any way to give constraints to both REF columns?
This works just fine:
CREATE TABLE Applications OF ApplicationType (
person SCOPE IS People,
competition SCOPE IS Competitions
)
OBJECT IDENTIFIER IS SYSTEM GENERATED;
Maybe you tried creating the table using or instead of , for separating the constraints(as seen in your comment).
It's also easy to test your constraints. Just create these two additional dummy tables:
CREATE TABLE People2 OF PersonType
OBJECT IDENTIFIER IS SYSTEM GENERATED;
CREATE TABLE Competitions2 OF CompetitionType
OBJECT IDENTIFIER IS SYSTEM GENERATED;
Then:
INSERT INTO People VALUES('p1');
INSERT INTO People2 VALUES('p21');
INSERT INTO Competitions VALUES('c1');
INSERT INTO Competitions2 VALUES('c21');
COMMIT;
INSERT INTO Applications
VALUES
(
(SELECT REF(p) FROM People p WHERE person = 'p1'),
(SELECT REF(c) FROM Competitions2 c WHERE competition = 'c21'),
SYSDATE
);
results in an ORA-22889 since the refered value is not in the specified scoped table(which is Competitions, not the dummy Competitions2).
You can test similarly using People2 instead of People.