We just migrated from Oracle 8i to Oracle 11g. In doing so we ran into a problem we have a variable called current_time. we use it as both a variable in various procedures and functions ans as well as column names in several tables. The references to the term 'CURRENT_DATE) looks to be in the neighborhood of a few thousand in our procview. When we upgraded, suddenly any time we were referring to the term current_date the new function was overriding the variables and column names. My question is how can we disable the reference to the oracle defined function?
You need to qualify the column name. Otherwise, Oracle's scope resolution rules will choose the function over the column
SQL> create table foo( current_date date );
Table created.
SQL> insert into foo values( date '2011-01-01' );
1 row created.
SQL> select current_date from foo;
CURRENT_D
---------
07-FEB-12
SQL> select f.current_date from foo f;
CURRENT_D
---------
01-JAN-11
Related
I have a db in sqllite and it has almost 140 tables and many columns. And I don't know which table contain what column I have a specific requirement to search for specific column name
.
For example I have a database called msg. And it has almost 100 tables after lots of try I am unable to find exact column name like I am searching for localid in db from all table. I am using Sqllitestudio to see the db.
My question is can I search for just a column name and in which table or in how many tables that particular column exist.
Start the sqlite commandline tool.
Ask the "table of tables" about anything mentioning " localid " in the creation statement.
create table toy1 (thisid int, aletter char(1), anotherint int);
create table toy2 (globalid int, aletter char(1), localid int);
select * from sqlite_master where sql like '% localid %';
Output (with .headers on, in SQLite 3.18.0):
type name tbl_name rootpage sql
---------- ---------- ---------- ---------- --------------------------------------------------------------
table toy2 toy2 3 CREATE TABLE toy2 (globalid int, aletter char(1), localid int)
Edit the "where" clause to make the filter tighter or more generous, depending on what you need.
I have used information on this site for awhile, and now have a large project that I need some of your expertise on. I work within an Oracle 11g environment and also have Cognos Report Studio 10.1
I am building a multitab report that displays an analysis of a department's outbound orders. I have created a custom table that holds approximately 30 columns of data. From here, there are over 150 calculations that must be performed on the table daily. An example of these calculations are
1) How many orders received today?
2) Of the orders received today, how many shipped same day?
3) How many orders are on hold?
Basically 100s of 4-5 line queries on the core table. I have thought about creating a second table and with the use of WITH clauses, performing the calculations in a procedure and inserting into the table.
To get to the question, has anyone written a procedure/package that performed a large amount of calculations and is there any links/webpages that can be suggested? My searches have not led me to any examples of a report of this nature being created and am wanting to make sure that my approach is as efficient as possible. Thanks in advance for any information/resources.
A table and stored procedure is a great idea. Some considerations:
Will you be archiving these facts per day.
Ie, do you want to be able to lookup the orders that were on hold 5 days ago, or is all of the data in the 150 questions only relevant for the current date?
You can have a table with 150 columns, one for each question. That may make sense if you are archiving data and need one record per day.
The alternative is to create an order fact table with just two or three fields:
Fact_Name VARCHAR2(30)
Order_Fact NUMBER(10,2)
Last_Update_Date DATE
Your oracle stored procedure would query and update the facts one at a time:
insert into ORDER_FACTS
select "ORDERS_RECEIVED" fact_name, count(*) order_fact, sysdate
from ORDER_TABLE
where rcv_date = trunc(sysdate);
commit;
If you are only wanting to keep one record per fact, you would do an update.
If the answer to some of your questions is not a number, you may need to keep a separate table for facts with VARCHAR2 type.
If you like the sound of this solution, I can setup an example procedure tomorrow.
Edit:
Since you are storing 30 days worth of data, I would create the table at the Date detail level, and have 1 column to store each result. For my example I just included 3 columns so you could get the idea. First, create the table to hold your order facts.
create table order_facts
( DT DATE,
ORD_RCV NUMBER,
SAME_DAY_SHIPPED NUMBER,
ON_HOLD NUMBER);
I suggest the DT field stores the date alone. This will make the table easier to join with your calendar table, which you can use to join these facts to other reports easily if they are based on tables with Calendar in their star schema.
Next, create the procedure to update them:
CREATE OR REPLACE PROCEDURE CALC_ORDER_FACTS ( iDate date := trunc(sysdate), iPurgeDays number := 0)
IS
ddate DATE;
dummy DATE;
/*
Calc_order_facts
Date Author Note
04/11/2013 XXX Created this procedure
Param iDate (optional, default trunc(sysdate)
Specify Date to calculate order facts for
Param iPurgeDays number (optional, default 0)
Specify how many days to retain data. Data older than iPurgeDays will be deleted.
If 0, purging is disabled.
*/
BEGIN
ddate := iDate;
IF iPurgeDays > 0 THEN
dbms_output.put_line('Purging data more than ' || to_char(iPurgeDays) || ' days old.');
begin
delete ORDER_FACTS
where DT < trunc(ddate-iPurgeDays);
commit;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Purge found no data.');
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
dbms_output.put_line('Purged failed, rollling back...');
rollback;
END;
END IF;
-- If date does not already exist in table, insert it
begin
select dt
into dummy
from order_facts
where dt = ddate;
EXCEPTION
WHEN NO_DATA_FOUND THEN
insert into order_facts
values (ddate, null, null, null);
commit;
END;
-- ORD_RCV
-- Calculate Orders received
update order_facts
set ord_rcv =
(select count(*) ord_rcv
from ORDER_TABLE
where rcv_date = ddate)
where dt = ddate;
commit;
-- SAME_DAY_SHIPPED
-- Calculate Orders received and shipped on ddate
update order_facts
set same_day_shipped =
(select count(*) same_day_shipped
from order_table
where rcv_dt = ddate
and ship_dt = ddate)
where dt = ddate;
commit;
-- ON_HOLD
-- Total orders on_hold
-- This method applies if you are only concerned with total on hold
update order_facts
set on_hold =
(select count(*) ON_HOLD
from order_table
where status = 'HOLD')
where dt = ddate;
commit;
END CALC_ORDER_FACTS;
I am trying to get list of all tables/views (in other words all objects) where a particular field is referenced using the system or catalog tables. I am using the following query.
select *
from dba_col_comments
where column_name like('SXX_AXXX_%')
order by 1;
However, the output is volatile. When I repeatedly run the same query without any changes the output is varies. For instance, it produced 9300 records and then 9350 after a couple of minutes and then 9347 after a couple of minutes.
I am observing the same behaviour in Teradata as well.
My theory would be - in a production enironment temporary objects that are created are probably getting an entry in the system/catalog tables.
Any thoughts/directions?
In Teradata you will find that as global temporary tables are instantiated (referenced by an SQL statement) records should be added to the data dictionary table TVM. These records are then dropped after the session logs off leaving just the base table record associated with the original CREATE GLOBAL TEMPORARY TABLE statement that was submitted.
You can find these instances using the view DBC.AllTempTables.
In Teradata, volatile tables are not maintained within the data dictionary.
EDIT - Your mileage may vary but this should get you started on Teradata
SELECT D1.DatabaseNameI AS DatabaseName_
, T1.TVMNameI AS TableName_
, F1.FieldName AS ColumnName_
FROM "DBC".TVM T1
INNER JOIN
"DBC".Dbase D1
ON D1.DatabaseId = T1.DatabaseId
INNER JOIN
"DBC".TVFields F1
ON F1.DatabaseId = T1.DatabaseId
AND F1.TableId = T1.TVMId
WHERE F1.FieldName = 'MyColumn'
--AND D1.DatabaseNameI IN ('{Database1}', ... '{Database99}') -- Filter on databases
AND F1.FieldType in ('i', 'i1', 'i2', 'i8') -- Integer, ByteInt, SmallInt, BigInt
--AND T1.TableKind IN ('T') -- Optional Filter to just tables.
AND NOT EXISTS
(SELECT 'x'
FROM "DBC".TempTables TT1
WHERE Tt1.TableId = T1.TVMId
)
;
In my project, I have a database in SQL which was working fine. But now I have to make the application support oracle db too.
Some limitations I found out was that in Oracle, there is no bit field and the table name cannot be greater than 30 char. Is there any other limitation that I need to keep in mind.
Any suggestion from past experience will be helpful.
If I recall correctly from my earlier Oracle days:
there's no IDENTITY column specification in Oracle (you need to use sequences instead)
you cannot simply return a SELECT (columns) from a stored procedure (you need to use REF CURSOR)
of course, all stored procs/funcs are different (Oracle's PL/SQL is not the same as T-SQL)
The SQL ISNULL counterpart in Oracle is NVL
select ISNULL(col, 0)...
select NVL(col, 0)...
You will also struggle if you attempt to select without a from in Oracle. Use dual:
select 'Hello' from DUAL
Bear in mind also, that in Oracle there is the distinction between PL/SQL (Procedural SQL) and pure SQL. They are two distinct and separate languages, that are commonly combined.
Varchar in Oracle Databases called
varchar2 is limited to 4000
characters
Oracles concept of temporary tables is different, they have a global redefined structure
by default sort order and string compare is case-sensitive
When you add a column to a select *
Select * from table_1 order by id;
you must prefix the * by the table_name or an alias
Select
(row_number() over (order by id)) rn,
t.*
from table_1 t
order by id;
Oracle doesn't distinguish between null and '' (empty string). For insert and update you ca use '', but to query you must use null
create table t1 (
id NUMBER(10),
val varchar2(20)
);
Insert into t1 values (1, '');
Insert into t1 values (2, null);
Select * from t1 where stringval = 0; -- correct but empty
Select * from t1 where stringval is null; -- returns both rows
ORACLE do not support TOP clause. Instead of TOP you can use ROWNUM.
SQL Server: TOP (Transact-SQL)
SELECT TOP 3 * FROM CUSTOMERS
ORACLE: ROWNUM Pseudocolumn
SELECT * FROM CUSTOMERS WHERE ROWNUM <= 3
I have the following statements in Oracle 11g:
CREATE TYPE person AS OBJECT (
name VARCHAR2(10),
age NUMBER
);
CREATE TYPE person_varray AS VARRAY(5) OF person;
CREATE TABLE people (
somePeople person_varray
)
How can i select the name value for a person i.e.
SELECT somePeople(person(name)) FROM people
Thanks
I'm pretty sure that:
What you're doing isn't what I'd be doing. It sort of completely violates relational principles, and you're going to end up with an object/type system in Oracle that you might not be able to change once it's been laid down. The best use I've seen for SQL TYPEs (not PL/SQL types) is basically being able to cast a ref cursor back for pipelined functions.
You have to unnest the collection before you can query it relationally, like so:
SELECT NAME FROM
(SELECT SP.* FROM PEOPLE P, TABLE(P.SOME_PEOPLE) SP)
That'll give you all rows, because there's nothing in your specifications (like a PERSON_ID attribute) to restrict the rows.
The Oracle Application Developer's Guide - Object Relational Features discusses all of this in much greater depth, with examples.
To insert query:-
insert into people values (
person_varray(person('Ram','24'))
);
To select :-
select * from people;
SELECT NAME FROM (SELECT SP.* FROM PEOPLE P, TABLE(P.somePeople) SP)
While inserting a row into people table use constructor of
person_varray and then the constructor
of person type for each project.
The above INSERT command
creates a single row in people table.
select somePeople from people ;
person(NAME, age)
---------------------------------------------------
person_varray(person('Ram', 1),
To update the query will be:-
update people
set somePeople =
person_varray
(
person('SaAM','23')
)