CREATE TABLE penalty(
member_id number(11) NOT NULL,
punishment_cost number(3),
punishment_rate number(3),
total_cost number(11)
);
CREATE TABLE member(
member_id number(11) NOT NULL PRIMARY KEY,
member_name varchar2(255) NOT NULL,
member_surname varchar2(255) NOT NULL,
gender varchar2(30) NOT NULL,
birthdate DATE,
phone varchar2(11),
mail varchar2(255) NOT NULL,
member_password varchar2(255) NOT NULL,
address varchar2(255),
status number(1),
role_id number(10) NOT NULL
);
CREATE TABLE item(
item_id varchar2(255) NOT NULL PRIMARY KEY,
member_id number(11),
publish_date DATE,
is_occupied NUMBER(1) NOT NULL,
publisher_id number(11) NOT NULL,
category_name varchar2(255) NOT NULL,
loan_id number(10)
);
CREATE TABLE current_loan(
loan_id number(10) NOT NULL PRIMARY KEY,
loan_date DATE,
due_date DATE
);
Penalty is a week entity , but I want to ask how to find the difference between the system date and the return date of an item that a member has borrowed, and fill in the member _id field in the penalty(week entity) table and the member _id, total cost fields in the penalty table. total cost = penalty_rate * days, but this trigger's run condition should run when the return date exceeds the system date.
For example
member takes a book start date - return date : today - tomorrow , but after 2 days trigger will be inserted a new row in penalty table but ı cannot do it. because sysdate-tomorrow
A trigger can only run when data is modified in the table. One way to approach this would be to use a view instead of a table to calculate the penalty at runtime instead of trying to store the static data. Also, your data model could use a little adjusting to make generating that info simpler. Consider this arrangement:
/* store all info about the member */
CREATE TABLE member(
member_id number(11) NOT NULL PRIMARY KEY,
member_name varchar2(255) NOT NULL,
member_surname varchar2(255) NOT NULL,
gender varchar2(30) NOT NULL,
birthdate DATE,
phone varchar2(11),
mail varchar2(255) NOT NULL,
member_password varchar2(255) NOT NULL,
address varchar2(255),
status number(1),
role_id number(10) NOT NULL
);
/* store all info about the item, including punishment rate */
CREATE TABLE item(
item_id varchar2(255) NOT NULL PRIMARY KEY,
publish_date DATE,
publisher_id number(11) NOT NULL,
category_name varchar2(255) NOT NULL,
punishment_rate number(3)
);
/* a loan is a relationship between member and item, with dates */
CREATE TABLE current_loan(
item_id number(11) NOT NULL,
member_id number(11) NOT NULL
loan_date DATE NOT NULL,
due_date DATE NOT NULL
);
/* calculate overdue fees for each member as of current sysdate */
CREATE OR REPLACE VIEW punishment AS
SELECT
m.member_name,
sum(i.punishment_rate*trunc(sysdate-l.due_date)) total_cost
FROM
member m
left join current_loan l on (l.member_id = m.member_id)
left join item i on (i.item_id = l.item_id)
WHERE
(sysdate - l.due_date) >= 1
GROUP BY m.member_name;
The view will show the total penalties for each member across all loans, based on the difference between current sysdate and due date, only for overdue returns. Because it is a view, the total amount is calculated at runtime and is always current. Alternatively, if you must store the actual total in a column, you could implement this as a materialized view that would refresh on a set schedule. This approach would only be recommended if you were performing so many calculations when querying the view that it affected performance of the query.
Note: You include a member_password column in your member table. not sure what you actually plan to store there, but storing the actual password for a user account is always a bad idea. At most you should only store a one way hash of the password, probably as a RAW data type.
Related
I am trying to create a table for bookings and want there to be a check constraint where the customer can only insert the D.O.B from a certain year to another certain year but keep getting the same error message
Any help would be very appreciated
`
create table guest
( Guest_ID varchar2(8) primary key,
Family_Name varchar2(20) not null,
Given_Name varchar2(20) not null,
Date_of_Birth date check (Date_of_Birth between date '01/01/1904' and
date '01/01/2004' ) not null,
Address varchar2(80) not null
);
`
Use the following code:
create table guest
( Guest_ID varchar2(8) primary key,
Family_Name varchar2(20) not null,
Given_Name varchar2(20) not null,
Date_of_Birth date check (Date_of_Birth between to_date('01/01/1904','DD/MM/YYYY') and
to_date('01/01/2004','DD/MM/YYYY')) not null,
Address varchar2(80) not null
);
The Tip from jarlh(comments) works. Problem might be your Date format.
create table guest
(Guest_ID varchar2(8) primary key,
Family_Name varchar2(20) not null,
Given_Name varchar2(20) not null,
Date_of_Birth date check (Date_of_Birth between date '1904-
01- 01' and date '2004-01-01' ) not null,
Address varchar2(80) not null
);
insert into guest values ('t','t','t','18-NOV-03','t')
works fine.
Fiddle
I would simplify that and prefer EXTRACT because you don't care about the day, but only want to check a range of years...
...CHECK (EXTRACT(YEAR FROM Date_of_Birth) BETWEEN 1904 and 2003 )...
...unless you really have to accept the 1st of January 2004 as valid date,too.
I am creating a flock management application with APEX with the following PL/SQL scheme:
-- SHEEP table
create table sheep (
sheep_id number(*,0) generated by default on null as identity,
eid varchar2(6) not null,
sex varchar2(6) not null,
name varchar2(45),
breed varchar2(255) not null,
birth date,
sheep_state varchar2(45) not null,
lambs number(*,0) not null,
lambs_sets number(*,0) not null,
markings varchar2(4000),
note varchar2(4000),
constraint sheep_pk primary key (sheep_id)
);
-- EVENT table
create table event (
event_id number(*,0) generated by default on null as identity,
sheep_id varchar2(6) not null,
name varchar2(255) not null,
event_date date not null,
description varchar2(4000) not null,
location varchar2(45) not null,
constraint event_pk primary key (event_id)
);
-- SALE table
create table sale (
sale_id number(*,0) generated by default on null as identity,
sheep_id varchar2(6) not null,
price number(*,2) not null,
sale_date date not null,
location varchar2(45) not null,
note varchar2(4000),
constraint sale_pk primary key (sale_id)
);
In this scheme, the SALE and EVENT tables reference the EID field of the SHEEP table (unique identifier of 5 numbers and one letter - representing the yellow tag they have in their ears). I am trying to create a Master Detail page that would link a sheep to specific events (what happened to the sheep) and a sales history (if it has been sold, when, where, for how much).
I tried to use both the Create Application Wizard and the Create Page Wizard but each time I get the same error:
Ajax call returned server error ORA-06531: Reference to uninitialized collection for Execute PL/SQL Code.
It still lets me continue in the wizard but when I want to select the details tables (SALE & EVENT), they don't even show up in selecting list (cf here).
Does someone have an idea? I am quite new to APEX and I might have missed something. Also, if you have any recommendations considering my relational scheme (change to make, improvements for efficiency), don't hesitate to tell me as well.
Thanks in advance!
There is no relationship between event and sheep or between sale and sheep. You state the SALE and EVENT tables reference the EID field of the SHEEP table but the database doesn't know about that, because that relationship has not been defined by way of a foreign key. A foreign key in a table references the primary key of the other table, you can't reference another column (like the EID), even if that is unique.
In your script, make sheep_id NUMBER in all tables and create a foreign key in SALE and EVENT. Like this:
-- SHEEP table
create table sheep (
sheep_id number(*,0) generated by default on null as identity,
eid varchar2(6) not null,
sex varchar2(6) not null,
name varchar2(45),
breed varchar2(255) not null,
birth date,
sheep_state varchar2(45) not null,
lambs number(*,0) not null,
lambs_sets number(*,0) not null,
markings varchar2(4000),
note varchar2(4000),
constraint sheep_pk primary key (sheep_id)
);
-- EVENT table
create table event (
event_id number(*,0) generated by default on null as identity,
sheep_id number not null,
name varchar2(255) not null,
event_date date not null,
description varchar2(4000) not null,
location varchar2(45) not null,
constraint event_pk primary key (event_id),
constraint fk_event_sheep
foreign key (sheep_id)
references sheep(sheep_id)
);
-- SALE table
create table sale (
sale_id number(*,0) generated by default on null as identity,
sheep_id number not null,
price number(*,2) not null,
sale_date date not null,
location varchar2(45) not null,
note varchar2(4000),
constraint sale_pk primary key (sale_id),
constraint fk_sale_sheep
foreign key (sheep_id)
references sheep(sheep_id)
);
This is the way to create a master detail relationship in relational database system and it should allow you to create a Master-Detail form in APEX as well.
First of all, I apologize for asking the same question again but the information on the old topics did not work in my oraclesql code and secondly there may be some syntax errors, I learned mysql in school last semester, but now we are learning oraclesql with old mysql information in the lesson, so i am a bit confused.
So my question is i want to create 3 related table (movie-casts-actor) but i am getting missing right parenthesis. trying to connect casts table to movie table with foreign key and actor table to casts table. what am i doing wrong? how spagetti is it?
CREATE TABLE Movie (
movie_id NUMBER(7) NOT NULL,
movie_name varchar2(50) NOT NULL ,
movie_director varchar2(50) NOT NULL ,
movie_year INT(4) NOT NULL ,
movie_duration INT(3) ,
movie_language varchar2(15) ,
movie_rating number(4,2) ,
PRIMARY KEY(movie_id),
CONSTRAINT is_unique UNIQUE(movie_id),
CONSTRAINT movie_id_checker CHECK(movie_id>0 and movie_id<=9999999)
);
CREATE TABLE Casts (
movie_id_fk INT(7) FOREIGN KEY REFERENCES Movie(movie_id) ,
cast_id INT(7) NOT NULL,
actor_fullname varchar2(50) NOT NULL ,
actor_role varchar2(50) ,
PRIMARY KEY(cast_id),
CONSTRAINT is_unique UNIQUE(cast_id),
CONSTRAINT cast_id_checker CHECK(cast_id>0 and cast_id<=9999999)
);
CREATE TABLE Actor (
cast_id_fk INT(7) FOREIGN KEY REFERENCES Casts(cast_id) ,
actor_id INT(7) NOT NULL,
actor_name CHAR(30) ,
actor_surname CHAR(25) ,
actor_gender CHAR(5) ,
actor_age CHAR(3) CONSTRAINT real_age_check CHECK(actor_age>0 AND actor_age<=150),
PRIMARY KEY(actor_id),
CONSTRAINT is_unique UNIQUE(actor_id),
CONSTRAINT actor_id_checker CHECK(actor_id>0 and actor_id<=9999999)
)
The errors are:
INT or NUMBER(4,0) and not INT(4)
You cannot have a unique key and a primary key on the same column.
An inline foreign key just need the REFERENCES keyword and does not need FOREIGN KEY.
Other issues:
You probably don't want actor name/surname as fixed-length CHAR strings and want to us variable-length VARCHAR2.
You probably want gender to be a code from a fixed list (which can be as long or as short as you find appropriate to describe the actors) rather than as a string.
You probably don't want to have an AGE column as that will be out of date as soon as the first birthday of an actor occurs; instead have a DATE_OF_BIRTH column that is a DATE data type and then you can calculate the age as and when necessary.
Using the table name as a prefix for every column is a waste of key strokes; you would be better to just name the columns for what they are without the prefix. Similar with fk as a suffix.
If you are using a NUMBER(7,0) for id values then you don't need to check that it is less than or equal to 9999999 as it is impossible to be a greater value; however, you can have zero or negative values so the check constraint for the lower bound may still be valid.
If you are using Oracle 12c or later then you should probably be using an IDENTITY column for the id values unless you are taking the id values from a 3rd party.
CREATE TABLE Movie (
id NUMBER(7,0) NOT NULL,
name varchar2(50) NOT NULL ,
director varchar2(50) NOT NULL ,
year NUMBER(4,0) NOT NULL ,
duration NUMBER(3,0),
language varchar2(15) ,
rating number(4,2) ,
PRIMARY KEY(id),
CONSTRAINT movie_id_checker CHECK(id>0)
);
CREATE TABLE Casts (
movie_id INT REFERENCES Movie(id) ,
id NUMBER(7,0) NOT NULL,
fullname varchar2(50) NOT NULL ,
role varchar2(50) ,
PRIMARY KEY(id),
CONSTRAINT cast_id_checker CHECK(id>0)
);
CREATE TABLE Actor (
cast_id NUMBER(7,0) REFERENCES Casts(id) ,
id NUMBER(7,0) NOT NULL,
name VARCHAR2(30) ,
surname VARCHAR2(25) ,
gender CHAR(1)
CHECK ( gender IN ( 'M', 'F', 'X', 'Y', 'Z' ) ),
date_of_birth DATE
CONSTRAINT real_age_check CHECK(date_of_birth >= DATE '1870-01-01' ),
PRIMARY KEY(id),
CONSTRAINT actor_id_checker CHECK(id>0)
);
db<>fiddle here
I am trying to run SQL statements in the Oracle 11g Express edition, where I am to create tables. Here is my SQL code:
CREATE TABLE STORE
(
StoreID INT PRIMARY KEY,
StoreName VARCHAR2(30) NOT NULL,
City VARCHAR2(30) NOT NULL,
Country VARCHAR2(30) NOT NULL CHECK Country in ('China','Egypt','United States','Spain','New Zealand','Mexico','Africa'),
Phone VARCHAR2(30) NOT NULL,
Fax VARCHAR2(30),
Email VARCHAR2(50) UNIQUE,
Contact VARCHAR2(30) NOT NULL,
UNIQUE (StoreName, City)
);
CREATE TABLE PURCHASE_ITEM
(
PurchaseItemID INT PRIMARY KEY,
StoreID INT NOT NULL REFERENCES STORE(StoreID) ON DELETE CASCADE ON UPDATE CASCADE,
"Date" DATE NOT NULL,
Description VARCHAR2(30) NOT NULL,
Category VARCHAR2(30),
PriceUsed NUMBER(15, 2)
);
CREATE SEQUENCE pur_seq
START WITH 500
INCREMENT BY 5;
CREATE OR REPLACE TRIGGER Purchase
BEFORE INSERT ON PURCHASE_ITEM
FOR EACH ROW
BEGIN
SELECT pur_seq.NEXTVAL
INTO :new.PurchaseItemID
FROM dual;
END;
CREATE TABLE SHIPPER
(
ShipperID INT PRIMARY KEY,
ShipperName VARCHAR2(30) NOT NULL,
Phone VARCHAR2(30) NOT NULL,
Fax VARCHAR2(30),
Email VARCHAR2(50) UNIQUE,
Contact VARCHAR2(30) NOT NULL
);
CREATE TABLE SHIPMENT
(
ShipmentID INT PRIMARY KEY Auto Increment,
ShipperID INT NOT NULL REFERENCES SHIPPER(ShipperID) ON DELETE CASCADE ON UPDATE CASCADE,
ShipperInvoiceNumber INT NOT NULL UNIQUE,
Origin VARCHAR2(30) NOT NULL,
Destination VARCHAR2(30) NOT NULL,
DepartureDate DATE,
ArrivalDate DATE
);
ALTER TABLE SHIPMENT AUTO_INCREMENT = 100;
CREATE TABLE SHIPMENT_ITEM
(
ShipmentID INT NOT NULL REFERENCES SHIPMENT(ShipmentID) ON DELETE CASCADE ON UPDATE CASCADE,
ShipmentItemID INT NOT NULL,
PurchaseItemID INT NOT NULL REFERENCES PURCHASE_ITEM(PurchaseItemID) ON DELETE CASCADE ON UPDATE CASCADE,
InsuredValue NUMBER(15, 2) NOT NULL defaut 100,
PRIMARY KEY (ShipmentID, ShipmentItemID)
);
It only ends up processing 4 statements and I keep getting these error messages:
CREATE TABLE STORE ( StoreID INT PRIMARY K - ORA-00906: missing left parenthesis
CREATE TABLE PURCHASE_ITEM ( PurchaseItemID INT - ORA-00907: missing right parenthesis
CREATE SEQUENCE pur_seq START WITH 500 INCREMENT BY 5 - ORA-00955: name is already used by an existing object
CREATE OR REPLACE TRIGGER Purchase BEFORE INSERT ON PURCHASE - ORA-00942: table or view does not exist
I am wholly unfamiliar with Oracle 11g. I am unsure if I am using the correct application in it for my assignment. I am only going by these instructions:
"For this assignment you are to write scripts to create tables and insert records. In oracle 11g I don’t want you to use the tools to generate the tables, you are required to write scripts to create the tables and records and will need to include the scripts for your submission."
Please, what am I doing wrong?
Let me summarize the problems with your scripts
First you have to enclose the check constraint with braces like below
CREATE TABLE STORE
(
StoreID INT PRIMARY KEY,
StoreName VARCHAR2(30) NOT NULL,
City VARCHAR2(30) NOT NULL,
Country VARCHAR2(30) NOT NULL CHECK (Country in ('China','Egypt','United States','Spain','New Zealand','Mexico','Africa')),
Phone VARCHAR2(30) NOT NULL,
Fax VARCHAR2(30),
Email VARCHAR2(50) UNIQUE,
Contact VARCHAR2(30) NOT NULL,
UNIQUE (StoreName, City)
);
Second, there is no ON UPDATE CASCADE in Oracle 11g so you need to remove it from the CREATE TABLE statement
Third, there is no Auto increment in Oracle 11G for columns So refer this SO for a workaround
Please let me know with these corrections whether your issue is resolved
hi i created tables using sql :-
create tables
create table customer (
cust_id number not null constraint customer_id_pk primary key,
cust_first varchar2(4000),
cust_last varchar2(4000),
cust_city varchar2(255),
)
;
create table medicine (
med_id number not null constraint medicine_id_pk primary key,
med_name varchar2(255),
med_info varchar2(4000),
med_prise number
)
;
create table the_order (
order_id number not null constraint the_order_id_pk primary key,
order_date date,
order_buyer varchar2(4000),
order_med varchar2(4000)
)
;
how do i connect the tables together into the order table i am using Apex to make a project.
i know its about foreign key but in the apex platform to show the forms as a report on one big table ?
Defining foreign keys is something done on the database, for a number of good reasons.
Your queries will work without them, but won't perform as well, and you could get dirty data over time.
It's all about the SQL. APEX is just a conduit to get the data from the database into a web page in front of the user's eyes.
You have a table design issue.
Provided you follow their best practices, it should figure out foreign keys and indexes for you.
Example
Quick SQL
customers
first_name /nn
last_name /nn
city
medicines
name /nn
info
price num /nn
orders
date /nn
customer_id /nn
order_lines
medicine_id /nn
medicine_name /nn
medicine_price num /nn
quantity num /nn
total num /nn
Generated SQL
-- create tables
create table customers (
id number generated by default on null as identity
constraint customers_id_pk primary key,
first_name varchar2(255 char) not null,
last_name varchar2(255 char) not null,
city varchar2(255 char)
)
;
create table medicines (
id number generated by default on null as identity
constraint medicines_id_pk primary key,
name varchar2(255 char) not null,
info varchar2(4000 char),
price number not null
)
;
create table orders (
id number generated by default on null as identity
constraint orders_id_pk primary key,
customer_id number
constraint orders_customer_id_fk
references customers on delete cascade not null,
the_date date not null
)
;
-- table index
create index orders_i1 on orders (customer_id);
create table order_lines (
id number generated by default on null as identity
constraint order_lines_id_pk primary key,
order_id number
constraint order_lines_order_id_fk
references orders on delete cascade,
medicine_id number
constraint order_lines_medicine_id_fk
references medicines on delete cascade not null,
medicine_name varchar2(255 char) not null,
medicine_price number not null,
quantity number not null,
total number not null
)
;
-- table index
create index order_lines_i1 on order_lines (medicine_id);
create index order_lines_i2 on order_lines (order_id);