Oracle Natural Joins and Count(1) - oracle

Does anyone know why in Oracle 11g when you do a Count(1) with more than one natural join it does a cartesian join and throws the count way off?
Such as
SELECT Count(1) FROM record NATURAL join address NATURAL join person WHERE status=1
AND code = 1 AND state = 'TN'
This pulls back like 3 million rows when
SELECT * FROM record NATURAL join address NATURAL join person WHERE status=1
AND code = 1 AND state = 'TN'
pulls back like 36000 rows, which is the correct amount.
Am I just missing something?
Here are the tables I'm using to get this result.
CREATE TABLE addresses (
address_id NUMBER(10,0) NOT NULL,
address_1 VARCHAR2(60) NULL,
address_2 VARCHAR2(60) NULL,
city VARCHAR2(35) NULL,
state CHAR(2) NULL,
zip VARCHAR2(5) NULL,
zip_4 VARCHAR2(4) NULL,
county VARCHAR2(35) NULL,
phone VARCHAR2(11) NULL,
fax VARCHAR2(11) NULL,
origin_network NUMBER(3,0) NOT NULL,
owner_network NUMBER(3,0) NOT NULL,
corrected_address_id NUMBER(10,0) NULL,
"HASH" VARCHAR2(200) NULL
);
CREATE TABLE rates (
rate_id NUMBER(10,0) NOT NULL,
eob VARCHAR2(30) NOT NULL,
network_code NUMBER(3,0) NOT NULL,
product_code VARCHAR2(2) NOT NULL,
rate_type NUMBER(1,0) NOT NULL
);
CREATE TABLE records (
pk_unique_id NUMBER(10,0) NOT NULL,
rate_id NUMBER(10,0) NOT NULL,
address_id NUMBER(10,0) NOT NULL,
effective_date DATE NOT NULL,
term_date DATE NULL,
last_update DATE NULL,
status CHAR(1) NOT NULL,
network_unique_id VARCHAR2(20) NULL,
rate_id_2 NUMBER(10,0) NULL,
contracted_by VARCHAR2(50) NULL,
contract_version VARCHAR2(5) NULL,
bill_address_id NUMBER(10,0) NULL
);
I should mention this wasn't a problem in Oracle 9i, but when we switched to 11g it became a problem.

My advice would be to NOT use NATURAL JOIN. Explicitly define your join conditions to avoid confusion and "hidden bugs". Here is the official NATURAL JOIN Oracle documentation and more discussion about this subject.

If it happens exactly as you say then it must be an optimiser bug, you should report it to Oracle.

you should try a count(*)
There is a difference between the two.
count(1) signifies count rows where 1 is not null
count(*) signifies count the rows

Just noticed you used 2 natural joins...
From the documentation you can only use a natural join on 2 tables
Natural_Join

Related

TRIGGERS_function

please help me to find the solution i have a project .
so my project is about a mobile repair store , we have some tables :
customers, mobiles, repairjob
//customer table
CREATE TABLE CUSTOMERS (
CUSTOMER_CPR NUMBER(9) PRIMARY KEY,
FIRST_NAME VARCHAR2(30) NOT NULL,
MID VARCHAR2(30)
LAST_NAME VARCHAR2(30) NOT NULL,
EMAIL VARCHAR2(30) NOT NULL UNIQUE,
HOME_TEL NUMBER(8) UNIQUE,
HOUSE_NO VARCHAR2(30) NOT NULL,
ROAD_NO VARCHAR2(30) NOT NULL,
BLOCK_NO VARCHAR2(30) NOT NULL,
CITY VARCHAR2(30) NOT NULL
);
//mobiles table
CREATE TABLE MOBILES (
MOB_ID NUMBER(8,0) PRIMARY KEY,
MODEL VARCHAR2(30) NOT NULL,
MOB_DECRIPTION VARCHAR2(100),
SERIAL_NUM VARCHAR2(30) UNIQUE,
MAKE VARCHAR2(50),
customer_cpr number(9),
);
//repair job table
CREATE TABLE REPAIR JOB (
JOB_NUM NUMBER primary key,
customer_cpr number(9)
EMP_ID NUMBER(8,0) NOT NULL,
DATE_RECEIVED DATE,
DATE_TO_RETURN DATE,
ITEM_ID NUMBER
);
so my question is to make a trigger function , we have assumed that the customer cannot have more than 3 repair jobs or can't fix more than 3 mobiles at one time until it finishes all. so how i make a triiger function ?

I am getting an error as invalid identifier but i couldnt find how

CREATE TABLE customer_details_1035
(
cust_ID Number(5) NOT NULL,
cust_last_name Varchar2(20) NOT NULL,
cust_mid_name Varchar2(4),
cust_first_name Varchar2(20),
account_no Number(5) Primary key,
account_type Varchar2(10) NOT NULL,
bank_branch Varchar2(25) NOT NULL,
cust_email Varchar2(30),
)
This is the error I get:
ORA-00904: : invalid identifier
Some dialects of SQL allow (or tolerate) a comma (,) after the last column specification in a create table statement.
According to the syntax diagrams, Oracle SQL doesn't allow this.
(So, the SQL parser will be looking for a column name (identifier) after the last ,. It finds a ) instead ... which is not a valid identifier.)
Solution: remove the extraneous comma.
CREATE TABLE customer_details_1035
(
cust_ID Number(5) NOT NULL,
cust_last_name Varchar2(20) NOT NULL,
cust_mid_name Varchar2(4),
cust_first_name Varchar2(20),
account_no Number(5) Primary key,
account_type Varchar2(10) NOT NULL,
bank_branch Varchar2(25) NOT NULL,
cust_email Varchar2(30), --Remove this comma(,)
);

Table using Foreign Key Oracle

I am having a problem linking two tables in oracle 11g express addition. I have looked on this site for assistance, but I am unable to find what I need.
My BOOKS table was loaded up using the following statement:
CREATE TABLE STATES(
ST VARCHAR2(2) PRIMARY KEY,
STATES VARCHAR2(20) NOT NULL
);
The CUSTOMERS table that I am trying to load is written as such:
CREATE TABLE CUSTOMERS(
CUST_ID NUMBER(10) PRIMARY KEY,
FIRST_NAME VARCHAR2(20) NOT NULL,
LAST_NAME VARCHAR2(20) NOT NULL,
STREET_ADDRESS_1 VARCHAR2(30) NOT NULL,
STREET_ADDRESS_2 VARCHAR2(20),
CITY VARCHAR2(20) NOT NULL,
ST VARCHAR2(2),
ZIP_CODE VARCHAR2(10) NOT NULL,
PHONE_NUMBER_1 VARCHAR2(20)NOT NULL,
PHONE_NUMBER_2 VARCHAR2(20),
EMAIL VARCHAR2(40) NOT NULL,
CREDIT_LIMIT NUMBER(7,2) NOT NULL,
FOREIGN KEY ST REFERENCES STATES(ST)
);
However, when I run the statement I get the following error:
ORA-00906: missing left parenthesis
00906. 00000 - "missing left parenthesis"
*Cause:
*Action:
I believe that the error is in the FOREIGN KEY portion of the statement, as I can load the table without that statement.
You have syntax error while declaring foreign key constraint
Correct one:
CREATE TABLE CUSTOMERS(
CUST_ID NUMBER(10) PRIMARY KEY,
FIRST_NAME VARCHAR2(20) NOT NULL,
LAST_NAME VARCHAR2(20) NOT NULL,
STREET_ADDRESS_1 VARCHAR2(30) NOT NULL,
STREET_ADDRESS_2 VARCHAR2(20),
CITY VARCHAR2(20) NOT NULL,
ST VARCHAR2(2),
ZIP_CODE VARCHAR2(10) NOT NULL,
PHONE_NUMBER_1 VARCHAR2(20)NOT NULL,
PHONE_NUMBER_2 VARCHAR2(20),
EMAIL VARCHAR2(40) NOT NULL,
CREDIT_LIMIT NUMBER(7,2) NOT NULL,
CONSTRAINT FK_CUSTOMERS FOREIGN KEY (ST) REFERENCES STATES(ST)
);
or
CREATE TABLE CUSTOMERS(
CUST_ID NUMBER(10) PRIMARY KEY,
FIRST_NAME VARCHAR2(20) NOT NULL,
LAST_NAME VARCHAR2(20) NOT NULL,
STREET_ADDRESS_1 VARCHAR2(30) NOT NULL,
STREET_ADDRESS_2 VARCHAR2(20),
CITY VARCHAR2(20) NOT NULL,
ST VARCHAR2(2),
ZIP_CODE VARCHAR2(10) NOT NULL,
PHONE_NUMBER_1 VARCHAR2(20)NOT NULL,
PHONE_NUMBER_2 VARCHAR2(20),
EMAIL VARCHAR2(40) NOT NULL,
CREDIT_LIMIT NUMBER(7,2) NOT NULL,
FOREIGN KEY (ST) REFERENCES STATES(ST)
);

Oracle table creation missing right parenthesis

This should be a pretty simple problem but I just can't see what is wrong. I am trying to create a table with a few check and not null constraints on said table, however I am getting a missing right parenthesis error when trying to execute the command.
CREATE TABLE students (
studentID NUMBER(5) PRIMARY KEY,
forename VARCHAR2(15) NOT NULL,
surname VARCHAR2(15) NOT NULL,
street VARCHAR2(20),
city VARCHAR2(15),
postcode VARCHAR2(10) NOT NULL,
dateOfBirth DATE() NOT NULL CHECK(dateOfBirth BETWEEN DATE '1999-01-01' AND SYSDATE),
gender VARCHAR2(10) CHECK(gender = 'male' OR gender = 'female' OR gender = 'both'),
category VARCHAR2(15) NOT NULL CHECK(category = 'first year undergraduate' OR caregory = 'postgraduate'),
fulltimeStudent VARCHAR(5) NOT NULL CHECK(fulltimeStudent = 'yes' OR fulltimeStudent = 'no'),
nationality VARCHAR(25) NOT NULL,
smoker VARCHAR(5) CHECK(smoker = 'yes' OR smoker = 'no') AND NOT NULL,
specialNeeds VARCHAR(30),
additionalComments VARCHAR(50),
status VARCHAR(15) NOT NULL CHECK(status = 'placed' or status = 'waiting')
);
Full error below -
There's no need for parenthesis at "DATE()".
Also, you cannot use SYSDATE in check constraints, you may wish to use a trigger instead, and there's a typo at "CAREGORY".
You can run it like this:
CREATE TABLE students (
studentID NUMBER(5) PRIMARY KEY,
forename VARCHAR2(15) NOT NULL,
surname VARCHAR2(15) NOT NULL,
street VARCHAR2(20),
city VARCHAR2(15),
postcode VARCHAR2(10) NOT NULL,
dateOfBirth DATE NOT NULL,
gender VARCHAR2(10) CHECK(gender = 'male' OR gender = 'female' OR gender = 'both'),
category VARCHAR2(15) NOT NULL CHECK(category = 'first year undergraduate' OR category = 'postgraduate'),
fulltimeStudent VARCHAR(5) NOT NULL CHECK(fulltimeStudent = 'yes' OR fulltimeStudent = 'no'),
nationality VARCHAR(25) NOT NULL,
smoker VARCHAR(5) NOT NULL CHECK(smoker = 'yes' OR smoker = 'no'),
specialNeeds VARCHAR(30),
additionalComments VARCHAR(50),
status VARCHAR(15) NOT NULL CHECK(status = 'placed' or status = 'waiting')
);
Edit-Added docs reference on sysdate in check constraints:
https://docs.oracle.com/cd/B28359_01/server.111/b28286/clauses002.htm
Conditions of check constraints cannot contain the following
constructs:
Subqueries and scalar subquery expressions
Calls to the functions that are not deterministic (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER, and USERENV)
Calls to user-defined functions
Dereferencing of REF columns (for example, using the DEREF function)
Nested table columns or attributes
The pseudocolumns CURRVAL, NEXTVAL, LEVEL, or ROWNUM
Date constants that are not fully specified

PL SQL trigger When Insert a table insert into another Table

I attached two table below I need a trigger when insert do_chd table in same time insert in do_chd_hist table And DO_MST table to DO_MST_HIST TAbLE
create table do_mst
( fdo_no varchar2(14) not null,
fdo_date date not null,
code_db varchar2(11),
db_name varchar2(25),
code_sdb varchar2(11),
sdb_name varchar2(25),
code_sst varchar2(11),
sst_name varchar2(25),
constraint fdo_no_pk primary key(fdo_no)
);
create table do_mst_hist
( fdo_no varchar2(14) not null,
fdo_date date not null,
code_db varchar2(11),
db_name varchar2(25),
code_sdb varchar2(11),
sdb_name varchar2(25),
code_sst varchar2(11),
sst_name varchar2(25),
constraint fdo_no_pk primary key(fdo_no)
);
create table do_chd
( fdo_no varchar2(14) not null,
itemcode varchar2(11) not null,
name varchar(27) not null,
unit_price varchar2(11),
req_qty number(11) not null,
total_price number(14),
unit varchar2(7),
constraint fdo_no_fk foreign key(fdo_no)
references do_mst(fdo_no)
);
create table do_chd_hist
( fdo_no varchar2(14) not null,
itemcode varchar2(11) not null,
name varchar(27) not null,
unit_price varchar2(11),
req_qty number(11) not null,
total_price number(14),
unit varchar2(7),
constraint fdo_no_fk foreign key(fdo_no)
references do_mst(fdo_no)
);
Can anybody help me to write this trigger?
While I agree with what being said in the comments, I don't think there's a reason to think twice about writing up a create trigger syntax, and I'm happy to show you the solution to your problem:
CREATE OR REPLACE TRIGGER do_chd_insert_trg
AFTER INSERT do_chd
FOR EACH ROW
DECLARE
sal_diff number;
BEGIN
insert into do_chd_hist
values (new.fdo_no, new.itemcode, new.name, new.unit_price, new.req_try, new.total_price, new.unit);
END;
/
You can use this syntax to generate the trigger to the second table, after changing the respectable column names.
You can read more about oracle trigger syntax here -
https://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm

Resources