Table -> Function dependency via a virtual column not in all_dependencies? - oracle

I've got the following objects:
CREATE FUNCTION CONSTFUNC RETURN INT
DETERMINISTIC
AS
BEGIN
RETURN 1;
END;
CREATE TABLE "FUNCTABLE" (
"ID" NUMBER(*,0) NOT NULL,
"VIRT" NUMBER GENERATED ALWAYS AS ("CONSTFUNC"()) NULL
);
however, the functable => constfunc dependency is not listed in all_ or user_ dependencies. Is there anywhere I can access this dependency information in the dictionary?

I just created your function and table in 11G (11.1) and can confirm your findings. I couldn't find anything in the Oracle docs either.
If you drop the function, the table status remains "VALID", but when you select from the table you get ORA-00904: "CHAMP"."CONSTFUNC": invalid identifier. This suggests that Oracle itself isn't aware of the dependency.
It might be worth asking this question on asktom.oracle.com, because Tom Kyte will have access to more information - he may even raise a bug about it if need be.

The expression used to generate the virtual column is listed in the DATA_DEFAULT column of the [DBA|ALL|USER]_TAB_COLUMNS views.

Related

User defined table types in Oracle

First of all usually I am working with MSSQL. But I have a stored procedure in MSSQL, which I need to use in Oracle now and since I am absolutely new to Oracle I have no idea at all how to do it correct.
I needed to use user defined table types in my MS SQL stored procedure because I am using "logical" tables in my stored procedure, which I also need to pass them to a dynamic sql statement within this procedure (using column names of "physical" tables as variables/parameters).
I've started to add the oracle function in a package I made before for another function. It looks like
TYPE resultRec IS RECORD
(
[result columns]
);
TYPE resultTable IS TABLE OF resultRec;
Function MyFunctionName([A LOT PARAMETERS]) RETURN resultTable PIPELINED;
I also described the layout of the tables (the user defined table types in MSSQL), which I want to use within this function in this package header.
So far so good, but now I don't really know where I have to declare my table variables or user defined table types. I also tried to put them in the package header, but if I am trying to use these tables in the package body, where I am describing my function, Oracle tells met, that the table or view does not exist.
I also tried it to describe the tables within the package body or in the block of my function, which looks like that:
FUNCTION MyFunctionName
(
[MyParameters]
)
RETURN resultTable PIPELINED is rec resultrec;
TYPE tableVariableA IS TABLE OF tableRecA;
TYPE tableVariableB IS TABLE OF tableRecB;
BEGIN
INSERT INTO tableVariableA
SELECT ColumnA, ColumnB FROM physicalTable WHERE[...];
[A LOT MORE TO DO...]
END;
But in this case Oracle also tells me, that it doesn't know the table or view.
I also tried a few more things, but at the end I wasn't able to tell Oracle what table it should use...
I would appreciate every hint, which helps me to understand how oracle works in this case. Thanks a lot!
You can't insert into a collection (e.g. PL/SQL table). You can use the bulk collect syntax to populate the collection:
SELECT ColumnA, ColumnB
BULK COLLECT INTO tableVariableA
FROM physicalTable
WHERE [...];
However, you might want to check this is an appropriate approach, since SQL Server and Oracle differ quite a bit. You can't use PL/SQL tables in plain SQL (at least prior to 12c), even inside your procedure, so you might need a schema-level type rather than a PL/SQL type, but it depends what you will do next. You might not really want a collection at all. Trying to convert T-SQL straight to PL/SQL without understanding the differences could lead you down a wrong path - make sure you understand the actual requirement and then find the best Oracle mechanism for that.

Hide sql from a view

for many reasons, we are protecting our Intellectual Property at its greatest and we already obfuscate and wrap our logic. Everything runs fine.
We have a concern about the views. In some cases we give to our clients some views based on their specific needs. That way we can offer 'em the right results. Otherwise, they sometimes try to build their own sql and they get wrong answers.
Is it possible to fill a materialized view based on a package or procedure? I understand that only a function can return something but I am maybe missing something. My actual alternative is to fill a table via a procedure but I am uncomfortable with that.
We are actually using Oracle 11
Any idea is welcome. Thanks!
You can provide a function which retruns a Nested Table.
CREATE TABLE SECRET_TABLE (col_1 NUMBER, col_2 VARCHAR2(10));
CREATE OR REPLACE TYPE t_secret_table_rec AS OBJECT (col_1 NUMBER, col_2 VARCHAR2(10));
CREATE OR REPLACE TYPE t_secret_table AS TABLE OF t_secret_table_rec;
CREATE OR REPLACE FUNCTION GetData RETURN t_secret_table AS
res t_secret_table;
BEGIN
-- Wrap this function
SELECT t_secret_table_rec(col_1, col_2)
BULK COLLECT INTO res
FROM SECRET_TABLE;
RETURN res;
END;
Then you can select the data like this:
SELECT * FROM TABLE(GetData);
However, it's quite some effort and you may face some problems regarding performance.

ORA-00942: table or view does not exist using iBatis

I am using MyBatis 3 to create a request (seen below) however, I am getting:
ORA-00942: table or view does not exist
where SYNONYM_A is a public Synonym for a table in another database...
I know the example doesn't really help, but the real question is, "Is there a special syntax for synonyms in Batis?" Has anyone done this, or failed, and can tell me, so I don't spend a great deal of effort, if it is not valid in Batis?
#Select("select * from SYNONYM_A where some_det_key in (SELECT DATA_KEY FROM SOME_PARENT_TABLE WHERE PARENT_KEY = 1234 AND (ATTACH_PARENT_FLG = 1 or ATTACH_PARENT_FLG is null) AND DATA_SRC = 'LV_SOME_DET') ORDER BY pair
Provide the select grant FROM the PARENT schema to the current schema once again for the table of which SYNONYM_A is a synonym of.
And is SYNONYM_A a synonym for a Table or a synonym of another SYNONYM in the PARENT schema?
In case it is, u need to provide grant from the ultimate base schema where the actual table is located once again 'WITH GRANT OPTION'
A public synonym does not mean that grants are not required from the schema in which the parent table lies(if the synonym and the table lies in two different schemas, that is). You need to clarify your concept of public synonyms :) .
But thats not the point here.
just do:
SELECT * SOME_TABLE"#"CONNECTION_TO_ANOTHER_DATABASE;
If this gives you ORA-XXXX: Table or view doesnot exist, then this is the cause.
There are two possibilities:
1.CONNECTION_TO_ANOTHER_DATABASE has got corrupted/doesnot exist.
You can check this by doing queries like :
Select sysdate from duals#CONNECTION_TO_ANOTHER_DATABASE;
Select * from user_objects#CONNECTION_TO_ANOTHER_DATABASE;
If this too gives you the same error then that's it, your CONNECTION_TO_ANOTHER_DATABASE is gone.
If this does not give any error and gives some valid o/p then:
2.Probably the "SOME_TABLE" at the remote database does not exist!
The answer is....
I was connected to the wrong database instance!! I had built extended AbstractRoutingDataSource, and was pulling the server name for the datasource from a primary database. I discovered that another individual had populated this table incorrectly, and pointed me to a database where the synonym did not exist.
Thank you for your responses, and your time.

DB2 duplicate key error when inserting, BUT working after select count(*)

I have a - for me unknown - issue and I don't know what's the logic/cause behind it. When I try to insert a record in a table I get a DB2 error saying:
[SQL0803] Duplicate key value specified: A unique index or unique constraint *N in *N
exists over one or more columns of table TABLEXXX in SCHEMAYYY. The operation cannot
be performed because one or more values would have produced a duplicate key in
the unique index or constraint.
Which is a quite clear message to me. But actually there would be no duplicate key if I inserted my new record seeing what records are already in there. When I do a SELECT COUNT(*) from SCHEMAYYY.TABLEXXX and then try to insert the record it works flawlessly.
How can it be that when performing the SELECT COUNT(*) I can suddenly insert the records? Is there some sort of index associated with it which might give issues because it is out of sync? I didn't design the data model, so I don't have deep knowledge of the system yet.
The original DB2 SQL is:
-- Generate SQL
-- Version: V6R1M0 080215
-- Generated on: 19/12/12 10:28:39
-- Relational Database: S656C89D
-- Standards Option: DB2 for i
CREATE TABLE TZVDB.PRODUCTCOSTS (
ID INTEGER GENERATED BY DEFAULT AS IDENTITY (
START WITH 1 INCREMENT BY 1
MINVALUE 1 MAXVALUE 2147483647
NO CYCLE NO ORDER
CACHE 20 )
,
PRODUCT_ID INTEGER DEFAULT NULL ,
STARTPRICE DECIMAL(7, 2) DEFAULT NULL ,
FROMDATE TIMESTAMP DEFAULT NULL ,
TILLDATE TIMESTAMP DEFAULT NULL ,
CONSTRAINT TZVDB.PRODUCTCOSTS_PK PRIMARY KEY( ID ) ) ;
ALTER TABLE TZVDB.PRODUCTCOSTS
ADD CONSTRAINT TZVDB.PRODCSTS_PRDCT_FK
FOREIGN KEY( PRODUCT_ID )
REFERENCES TZVDB.PRODUCT ( ID )
ON DELETE RESTRICT
ON UPDATE NO ACTION;
I'd like to see the statements...but since this question is a year old...I won't old my breath.
I'm thinking the problem may be the
GENERATED BY DEFAULT
And instead of passing NULL for the identity column, you're accidentally passing zero or some other duplicate value the first time around.
Either always pass NULL, pass a non-duplicate value or switch to GENERATED ALWAYS
Look at preceding messages in the joblog for specifics as to what caused this. I don't understand how the INSERT can suddenly work after the COUNT(*). Please let us know what you find.
Since it shows *N (ie n/a) as the name of the index or constraing, this suggests to me that is is not a standard DB2 object, and therefore may be a "logical file" [LF] defined with DDS rather than SQL, with a key structure different than what you were doing your COUNT(*) on.
Your shop may have better tools do view keys on dependent files, but the method below will work anywhere.
If your table might not be the actual "physical file", check this using Display File Description, DSPFD TZVDB.PRODUCTCOSTS, in a 5250 ("green screen") session.
Use the Display Database Relations command, DSPDBR TZVDB.PRODUCTCOSTS, to find what files are defined over your table. You can then DSPFD on each of these files to see the definition of the index key. Also check there that each of these indexes is maintained *IMMED, rather than *REBUILD or *DELAY. (A wild longshot guess as to a remotely possible cause of your strange anomaly.)
You will find the DB2 for i message finder here in the IBM i 7.1 Information Center or other releases
Is it a paging issue? we seem to get -0803 on inserts occasionally when a row is being held for update and it locks a page that probably contains the index that is needed for the insert? This is only a guess but it appears to me that is what is happening.
I know it is an old topic, but this is what Google shown me on the first place.
I had the same issue yesterday, causing me a lot of headache. I did the same as above, checked the table definitions, keys, existing items...
Then I found out the problem was with my INSERT statement. It was trying to insert to identical records at once, but as the constraint prevented the commit, I could not find anything in the database.
Advice: review your INSERT statement carefully! :)

How to get information about a User-Defined Type?

In simplicity, PL/SQL generally follow the following:
DECLARE
Variable declaration
BEGIN
Program Execution
EXCEPTION
Exception handling
END;
I am quite new to PL/SQL and i am looking at the variable declaration section where i would like to find out more information on SALES_PRODUCT_TY_LIST.
Is there a table i may look up to check on information on SALES_PRODUCT_TY_LIST, such as checking out table column information from all_tab_cols view?
CREATE OR REPLACE PROCEDURE GET_DISCOUNTS
(
v_have_list SALES_PRODUCT_TY_LIST
)
IS
QUERY VARCHAR(5000);
...
Thanks.
The Oracle database has an extensive data dictionary (what some other DBMS products call the INFORMATION SCHEMA). You can find all the views here. Alas, the revised ToC structure makes it harder to find something in the 11g documentation unless you already know what you're looking for, so use the index instead. 8-)
Anyway, the views you need to query are ALL_TYPES and ALL_TYPE_ATTRS.
This seems to be user defined collection type. You can find some information about it querying all_types/user_types view:
select * from user_types where type_name = 'SALES_PRODUCT_TY_LIST'
The definition of the type can be found for example by querying all_source/user_source view:
select text from user_source where name = 'SALES_PRODUCT_TY_LIST' order by line
Try this to get DDL:
SELECT dbms_log.substr(dbms_metadata.get_ddl('TYPE', 'SALES_PRODUCT_TY_LIST'), 32767,1)
FROM DUAL;
see: http://www.myoracleguide.com/s/gen_schema.htm
Ok i found something:
select *
from all_objects
where object_name like 'SALES%';

Resources