Namen VARCHAR(30) NULL

Werbung
TA.DMG.H0801
Datenmanagement
SQL Projekt
Gruppe 9
Studenten:
Thomas Stuber
Michael Studer
Modulverantwortlicher:
Thomas Olnhoff
Horw, 18.12.2008
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
1 ER-Diagramm
Seite 2 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
2 Tabellen
2.1 Grundtabellen
-- 06.11.2008 | DMG
--- Gruppe 9 | Michael Studer & Thomas Stuber
-CREATE TABLE Lieferanten
(
LieferantenNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Namen VARCHAR(30) NULL,
Adresse VARCHAR(50) NULL,
BankAccount VARCHAR(30) NULL
);
CREATE TABLE Mitarbeiter
(
MitarbeiterNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Namen VARCHAR(30) NULL,
Gehalt NUMERIC(6,2) NULL,
Geburtstag DATETIME NULL,
Adresse VARCHAR(50) NULL,
BankAccount VARCHAR(30) NULL
);
CREATE TABLE Maschine
(
MaschinenNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Beschreibung VARCHAR(50) NULL,
ServiceInterval INT NULL,
LastServiceMitarbeiterNr INT NULL REFERENCES Mitarbeiter
);
CREATE TABLE Teile
(
TeileNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Beschreibung VARCHAR(50) NULL,
Preis NUMERIC(9,2) NULL,
Groessenangabe INT NULL,
Stock INT NULL,
LieferantenNr INT NULL REFERENCES Lieferanten,
MaschinenNr INT NULL REFERENCES Maschine
);
CREATE TABLE ProduktionsProzess
(
ProduktionsNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
Tag DATETIME NULL,
ProduktionsProzess INT NULL REFERENCES ProduktionsProzess,
ReservierteMitarbeiterNr INT NULL REFERENCES Mitarbeiter,
BestehtAusTeilen INT NULL REFERENCES Teile,
AnzTeile INT NULL
);
CREATE TABLE Kundenbestellungen
(
BestellNr INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
KundenNr INT NULL,
Liefertermin DATETIME NULL,
AnzTeile INT NULL,
ProduktionsNr INT NULL REFERENCES ProduktionsProzess
);
CREATE TABLE IsPartOf
(
Oberteil INT NOT NULL,
Unterteil INT NOT NULL,
Amount INT NULL,
FOREIGN KEY (Oberteil) REFERENCES Teile,
FOREIGN KEY (Unterteil) REFERENCES Teile,
PRIMARY KEY (Oberteil, Unterteil)
);
Seite 3 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
CREATE TABLE CanOperate
(
MitarbeiterNr INT NOT NULL,
MaschinenNr INT NOT NULL,
FOREIGN KEY (MitarbeiterNr) REFERENCES Mitarbeiter,
FOREIGN KEY (MaschinenNr) REFERENCES Maschine,
PRIMARY KEY (MitarbeiterNr, MaschinenNr)
);
2.2 Zusatztabelle: Arbeitstage
create table arbeitstag(
tag datetime primary key
)
Go
2.2.1
Füllen der Arbeitstage
CREATE procedure mkTage(@anz int, @start datetime)
BEGIN
DECLARE @i int
SET @i=1
AS
WHILE (@i<=@anz)
BEGIN
if ( datepart(weekday, @start + @i) between 2 and 6)
-- no workday on Saturday and Sunday
insert into arbeitstag(tag) values(@start + @i)
set @i = @i
+ 1
END
END
Go
-- DB-Prozedur ist kreiert. Nachfolgend wir die Tabelle mit Daten gefüllt
execute mkTage 100, {d'2008-12-01'}
go
select * from Arbeitstag
--Kontrolle der Tabelle
Seite 4 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
3 Ablauf
Seite 5 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
4 SQL Prozedur für Produktion
-- Prozedur für das Reservieren aller nötigen Komponenten
create procedure reservation(@teil int, @anz int, @dayDone datetime out, @firstProduction int
out) as
BEGIN
declare @tid int, @tanz int, @tag datetime, @mitarbeiter int,
@pos int, @oldpos int,@oneDay datetime;
declare rs cursor local for
with th(Oberteil, Unterteil, amountO,amountU,pos) as
(select Oberteil ,Unterteil, @anz , Amount, 1 from isPartOf where Oberteil=@teil
union all
select ip.Oberteil,ip.Unterteil, th.amountO* th.amountU,ip.Amount, pos+1 from
(isPartOf ip join th on th.Unterteil=ip.Oberteil) join Teile t on ip.Oberteil =
t.TeileNr
where t.LieferantenNr is NULL)
select Oberteil, amountO, pos from th, Teile t where th.Oberteil=t.TeileNr order by
th.pos desc;
set @firstProduction = null
open rs
fetch next from rs into @tid, @tanz, @pos -- Einmaliger fetch-Durchlauf
if @@FETCH_STATUS <> 0 return -- exit
select @tag= min(tag) from arbeitstag where tag>=current_timestamp -- frühstmöglicher Tag
set @dayDone = @tag
set @oldPos = @pos
WHILE @@FETCH_STATUS = 0
BEGIN
if (@oldPos<>@pos)
begin
set @tag = dateadd(day,1,@dayDone)
set @oldPos = @pos
end
select top 1 @mitarbeiter = c.MitarbeiterNr, @oneDay=a.tag
from arbeitstag a, canOperate c, Teile t
where t.TeileNr = @tid and t.MaschinenNr = c.MaschinenNr and a.tag >= @tag and
not exists (select null from ProduktionsProzess p where p.Tag = a.tag and
(p.BestehtAusTeilen = @tid or p.ReservierteMitarbeiterNr = c.MitarbeiterNr) )
order by a.tag;
if (@oneDay>@dayDone) set @dayDone = @oneDay
insert into ProduktionsProzess(Tag, ProduktionsProzess, ReservierteMitarbeiterNr,
BestehtAusTeilen,
AnzTeile ) values(@oneDay, @firstProduction, @mitarbeiter, @tid, @tanz)
set @firstProduction = @@IDENTITY
fetch next from rs into @tid, @tanz, @pos
END
-- alle teile reserviert
CLOSE rs
DEALLOCATE rs
END
go
-- test der Prodzedur
begin
declare @d datetime, @r int
execute reservation 1,2, @d out, @r out
print @d
print @r
end
Seite 6 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
5 Java Code
package ch.hslu.dmg;
import java.sql.*;
/**
* Diese Klasse erstellt eine DB-Connection sowie ruft die Produktionsprozedur auf.
* @author tstuber
*/
public class simpleJdbc {
public static Connection conn;
/**
* Main-Methode. In dieser gibt man den Kundenauftrag ein.
* @param args
* @throws java.sql.SQLException
*/
public static void main(String args[]) throws SQLException {
try {
Class.forName(
"com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(
"jdbc:sqlserver://localhost;Database=dmg_projekt", "sa", "xxx");
// db-server with database, user and password
System.out.println("database connection ok");
java.sql.Date d = //new java.sql.Date(new java.util.Date().getTime());
java.sql.Date.valueOf("2008-12-31");
dbProcCall(1, 2, d); //Typ ID (1 = Velo), Anzahl, Datum
conn.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
/**
* Methode zum Aufrufen des Produktionsvorgangen. Kann die Produktion aus
* bestimmten Gründen nicht vollzogen werden - z.B. da es zu spät produziert
* werden kann, wird ein Rollbak ausgeführt und die Transaktion wird rückgängig
* gemacht. Ansonsten folgt ein Commit, was die Daten in die Datenbank schreibt.
*
* @param teilId
ID des obersten zu produzierenden Teiles. In diesem
*
Fall steht die ID=1 für ein Velo.
* @param anz
Anzahl der zu erstellenden Oberteile resp. Anz. Velos
* @param dayDeliveryWanted Datum, an welchem man die Velos produziert haben möchte
*/
protected static void dbProcCall(int teilId, int anz, java.sql.Date dayDeliveryWanted) {
try {
conn.setAutoCommit(false); // global conn
//Reihenfolge: @teil int, @anz int, @dayDone datetime out, @ProduktionsProzess
int out
CallableStatement cs = conn.prepareCall("{call reservation(?,?,?,?)}");
cs.setInt(1, teilId);
cs.setInt(2, anz);
cs.registerOutParameter(3, java.sql.Types.DATE);
cs.registerOutParameter(4, java.sql.Types.INTEGER);
cs.execute();
//Auslesen der Rückgabewert der Prozedur:
// - Datum, bis wann produziert wurde
// - ID für den Produktionsauftrag
java.sql.Date dayProductionDone = cs.getDate(3);
Integer ProduktionsNr = cs.getInt(4);
//Wenn entsprechend dem Wunschdatum oder frühzeitiger, dann folgt
//ein Eintrag in die Kundenaufträge sowie anschliessend ein commit.
if (ProduktionsNr > 0) {
//java.sql.Date dayProductionDone = cs.getDate(3);
System.out.println("Prod. Fertig: " + dayProductionDone);
System.out.println("Lieferwunsch: " + dayDeliveryWanted);
if (dayDeliveryWanted.compareTo(dayProductionDone) >= 0) {
PreparedStatement ps = conn.prepareStatement(
"insert into Kundenbestellungen(KundenNr," +
Seite 7 von 8
TA.DMG.H0801 – SQL Projekt
Michael Studer | Thomas Stuber
"Liefertermin,AnzTeile,ProduktionsNr) " +
"values(666,?,?,?)");
ps.setDate(1, dayProductionDone);
ps.setInt(2, anz);
ps.setInt(3, ProduktionsNr);
ps.execute();
System.out.println("committing");
conn.commit();
return;
}
}
//Rollback falls etwas fehlschlägt
System.out.println("rolling back");
conn.rollback();
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
}
}
Seite 8 von 8
Herunterladen