What to use: Record or Cursor? - sql

Create a PL/SQL block to retrieve and display data for all pledges made in a specified month. One row of output should be displayed for each pledge. Include the following in each row of output:
• Pledge ID, donor ID, and pledge amount
• If the pledge is being paid in a lump sum, display “Lump Sum”.
• If the pledge is being paid in a monthly payments, display “Monthly - #” (with the # representing the number of months for payment)
• The list should be sorted to display all lump sum pledges first.
here is the table struc.
CREATE TABLE DD_Pledge (
idPledge number(5),
idDonor number(4),
Pledgedate DATE,
Pledgeamt number(8,2),
idProj number(5),
idStatus number(2),
Writeoff number(8,2),
paymonths number(3),
Campaign number(4),
Firstpledge char(1),
CONSTRAINT pledge_id_pk PRIMARY KEY(idPledge),
CONSTRAINT pledge_idDonor_fk FOREIGN KEY (idDonor)
REFERENCES dd_donor (idDonor),
CONSTRAINT pledge_idProj_fk FOREIGN KEY (idProj)
REFERENCES dd_project (idProj),
CONSTRAINT pledge_idStatus_fk FOREIGN KEY (idStatus)
REFERENCES dd_status (idStatus));
I tried to use record but seems that record is not going to work as it gives me error when the specified month has more then one pledge. Is there a way to do it using record (coz this is and assignment we take it after we covered the record)
Maybe cursor will be a good choice but due to the point mentioned earlier I'd like to know what are the ways to solve this one.

SELECT
p.idPledge,
p.idDonor,
p.Pledgeamt as this_payment,
case
when p.paymonths = 0 then 'Lump Sum'
else 'Monthly - ' || p.paymonths
end as payment_method
FROM
dd_pledge p
WHERE
TRUNC(p.Pledgedate) >= '01-Mar-2010' AND TRUNC(p.Pledgedate) < '01-Apr-2010'
order by
4
Assuming you'll add your month's start/end dates as required.

Related

Creating a view between two tables in SQL

I'm having trouble creating a view between two tables, as I'm quite new to SQL. I need to create a view which will show which employees have carried out work as consultants within the past 14 days. The result of the view should also display this kind of layout:
14 day consultancy report
-----------------------------------------------
Employee Helvin Paul worked for 6 hours for factory ltd chargeable £351
The two tables I assume you will need to join together are the Employee table and also the Consultancy table. I will show both below as I have them in a text file from when I was creating these tables:
create table Funtom_employee
(
emp_ID Number(3) primary key,
Emp_firstname varchar2(50) not null,
Emp_surname varchar2(50),
Emp_department Number(2) constraint FK_funtom_dept references
funtom_department,
emp_street varchar2(50),
emp_town varchar2(50),
emp_district varchar2(50),
Emp_grade Number(3) default 4 constraint chk_emp_grd check (Emp_grade between 1 and 9),
Emp_site varchar2(30) default 'LONDON',
constraint FK_funtom_grade funtom_grade references funtom_department
);
create table Funtom_consultancy
(
consultancy_ID Number(3) primary key,
Consultancy_emp Number(3) constraint cns_emp references funtom_employee,
Consultancy_hours Number(4,2) constraint consultancy_check check (Consultancy_hours > 1),
Consultancy_client Number(3) references funtom_customer,
Consultancy_date DATE,
Consultancy_activity Number(3) references funtom_activity
);
Thanks to anyone that can help with this create view and for your time
A view can be created using the CREATE VIEW statement. An example based on your data is listed below.
CREATE VIEW consultancy_report as
select
Funtom_employee.Emp_firstname,
Funtom_consultancy.Consultancy_date,
from
Funtom_employee
join Funtom_consultancy
on Funtom_employee.emp_id = Funtom_consultancy.Consultancy_emp
You can add whatever other fields you need from either table in the select clause of the query. I've demonstrated one field from both tables.
If you want output explicitly as listed in your sample, you will need to concatenate several fields together as one string. Since this feels like a homework question, I will leave that as an exercise for you.

Inserting TIME into table SQL

I'm trying to insert a TIME value in a table in SQL Developer, but I get the current month returned. I am using Date as the constraint when creating the table. Sorry for the poorly written code, I'm not familiar with SQL.
INSERT INTO DELIVERY(ORDER_ID, DELIVERY_ID, DELIVERY_DATE, DELIVERY_TIME)
VALUES(1, 1565412,('06/Sep/12'),(TO_DATE('16:18:14', 'hh24:mi:ss')));
Output:
ORDER_ID DELIVERY_ID DELIVERY_DATE DELIVERY_TIME
1 1565412 06-SEP-12 01-FEB-15
2 8456233 24-MAR-12 01-FEB-15
3 8412654 21-JUN-12 01-FEB-15
4 1124335 03-JUN-11 01-FEB-15
5 7218854 30-AUG-11 01-FEB-15 `
Here is the table:
CREATE TABLE DELIVERY (
ORDER_ID NUMBER(7),
DELIVERY_ID NUMBER(7) CONSTRAINT DELIVERY_ID_NN NOT NULL,
DELIVERY_DATE DATE CONSTRAINT DELIVERY_DATE_NN NOT NULL,
DELIVERY_TIME DATE CONSTRAINT DELIVERY_TIME_NN NOT NULL,
PRIMARY KEY(DELIVERY_ID),
FOREIGN KEY (ORDER_ID) REFERENCES ORDERS(ORDER_ID)
);
When I 'SELECT delivery_time FROM DELIVERY` I want to be shown the time I have inserted into the table, not the date. I don't understand why it shows me 01-FEB-15
Your time is being stored ok. However, you need to put a mask on your DELIVERY_TIME column to display only the time. Try this query:
select order_id, delivery_id, delivery_date, to_char(delivery_time,'hh24:mi:ss')
from delivery
You can also set your NLS settings in SQL Developer to display the time by default in the menu
Tools
Preferences
Database
NLS,
then set the field Date Format (this is in version 4.0.0.13, I don't know if it changes in other versions).

How to update the date for a specific ID in Oracle SQL?

I'm setting up a database for a scuba diving company and have a SQL table with values for Student ID (SID), Instructor ID (IID), Item Borrowed (ITEMID), Equipment Borrow Date (BorrowDate), and Equipment Return Date (ReturnDate). How do I change the Equipment Return Date for one of the students? I'd like to add an extra 2 days to the ReturnDate. I created the Borrows table like this:
CREATE TABLE BORROWS(
SID CHAR(15),
ITEMID CHAR(15),
IID CHAR(15),
BORROW_DATE DATE,
RETURN_DATE DATE,
PRIMARY KEY(SID, ITEMID),
FOREIGN KEY(SID) REFERENCES STUDENT(SID) ON DELETE CASCADE,
FOREIGN KEY(ITEMID) REFERENCES EQUIPMENT(ITEMID) ON DELETE CASCADE,
FOREIGN KEY(IID) REFERENCES INSTRUCTOR(SSN) ON DELETE CASCADE
);
I tried doing this in my SQL file:
SELECT SID, ADD_DATE(RETURN_DATE, INTERVAL 2 DAY)
FROM BORROWS
WHERE SID = '005' AND IID = '108';
I'm getting this error back:
SELECT SID, ADD_DATE(RETURN_DATE, INTERVAL 2 DAY)
*
ERROR at line 1:
ORA-00907: missing right parenthesis
Can't figure out where the error is in my code...
Adding two days to a date is as simple as + 2.
select return_date + 2
from borrows
where sid='005'
and iid='108'
The syntax you are looking for might be:
select (return_date + INTERVAL '2' DAY)
from borrows
where sid='005'
and iid='108'

How can I get this query to print a record that only exists in one table?

I am trying to create a query that will accept a date from the user and display information from two tables based on this date. This works for all of my tests except my last test. My last test, I enter a date that should return a record that only exists in the expmast table and does not exist in the expbycc table. When I enter the date to try and get this record to be returned, it tells me no records have been found. I know this is because in my where, i have an AND that checks if M.ExpNum = C.ExpNUm which isn;t true for this record because it only exists in one table. I can not figure out how to get this query to work. Any help/advice is greatly appreciated. Below is my script, followed by the table structures used for this query, thank you.
Script:
ACCEPT Date PROMPT 'Enter a date:';
SELECT M.ExpNum, EDate, IsCash, StoreCode, CashAmt, CType, CCNum, Amt
FROM ExpMast M, ExpByCc C
WHERE EDate = to_date('&Date','mm-dd-yy')
AND M.ExpNum = C.ExpNum;
Tables:
CREATE TABLE EXPMAST
(ExpNum NUMBER(2,0) NOT NULL PRIMARY KEY,
EDate DATE,
IsCash VARCHAR2(1),
StoreCode VARCHAR2(4),
CONSTRAINT fk_STORE_EXPMAST FOREIGN KEY (StoreCode)
REFERENCES STORE (Code)
);
CREATE TABLE ExpByCC
(ExpNum NUMBER(2,0) NOT NULL,
CType VARCHAR2(1) NOT NULL,
CCNum VARCHAR2(16) NOT NULL,
Amt DECIMAL(5,2),
CONSTRAINT fk_CRCARD_ExpByCC FOREIGN KEY (CType, CCNum)
REFERENCES CRCARD (CType, CCNum),
CONSTRAINT fk_EXPMAST_ExpByCC FOREIGN KEY (ExpNum)
REFERENCES EXPMAST (ExpNum),
CONSTRAINT pk_ExpByCC PRIMARY KEY (ExpNum, CType, CCNum)
);
You need a left outer join. And you can't express an outer join using your implicit join syntax. You want to use explicit joins in the from clause.
A simple rule: NEVER use commas in the from clause.
Now, it is easy:
SELECT M.ExpNum, EDate, IsCash, StoreCode, CashAmt, CType, CCNum, Amt
FROM ExpMast M LEFT OUTER JOIN
ExpByCc C
ON M.ExpNum = C.ExpNum AND
WHERE M.EDate = to_date('&Date','mm-dd-yy') AND
C.ExpNum IS NULL;

How to compute a column value in oracle 10g?

create table ord_tbl
(
ord_id number(10) primary key,
ord_name varchar2(20),
quantity number(20),
cost_per_item number(30),
total_cost number(30)--This colm shud be (quantity*cost_per_item),
ord_date date
)
So when I insert rows then the 'total_cost' should automatically get generated and inserted into a table
10g doesn't have this feature. Instead, use a view:
create table ord_tbl
(
ord_id number(10) primary key,
ord_name varchar2(20),
quantity number(20),
cost_per_item number(30),
ord_date date
);
create view vw_ord_tbl as
select ord_id, ord_name, quantity, cost_perId, (quantity*cost_per_item) as total_cost, ord_date
from ord_tbl;
The alternative would be to have the column in the table to maintain the value using a trigger -- for both updates and inserts. I would suggest using the view, because maintaining the triggers adds a lot of maintenance overhead.
EDIT (by Jason):
In 11g you can create a virtual column in the table definition.
create table ord_tbl (
ord_id number(10) primary key,
ord_name varchar2(20),
quantity number(20),
cost_per_item number(30),
total_cost as (quantity*cost_per_item),
ord_date date
)
Like Gordon Linoff answered, you can create a view. Alternatively you can create a trigger and store the actual value:
create trigger tiua_ord_tbl
on ord_tbl after insert or update
for each row
begin
:new.total_cost := :new.quantity * :new.cost_per_item;
end;
The advantage of storing the data, is that you can access it faster and index it if you need. The disadvantage is that you store redundant data (it can be calculated at runtime) and it requires more storage space.
I would advise to use the view at first, and only start storing the value in the table if you need this 'cached' version for performance.