03. maj 2007 - 18:58Der er
23 kommentarer og 2 løsninger
Database opbygning
Hej Experter
Jeg skal igang med at lave et database projekt.
Kort fortalt indeholder databasen nogle medarbejdere som hver især skal indeholde nogle jobfunktioner. Altså hvilke fagområder de mestrer.
Hvis jeg vidste på forhånd hvilke jobfunktioner der var tale om ville det ikke være noget problem. Men der skal være mulighed for at tilføje nye jobfunktions-grupper og tilknytte medarbejdere til den gruppe. Så de skal altså have mulighed for at være tilknyttet flere jobfunktioner.
Jeg kan ikke rigtigt gennemskue hvordan jeg opbygger databasen bedst.
Kan man evt. lave et felt som indeholder alle de jobfunktioner som medarbejderen mestrer, og så lave et select statement som kigger i det felt og ser om feltet indeholder fx. "programmør"? Selvom feltet også indeholder andre ord.
Kan det lade sig gøre, og er der evt. en nemmere opbygningsmetode?
Tak fordi du læste hele denne smøre, nu håber jeg bare at du sidder med den gyldne sten i hånden.
Jeg er enig med neoman. Men jeg ville dog lave en ændring : Tabel Medarbejdere_i_Funktioner : Medarbejder_FunktionID(autogeneret), MedarbejderID, FunktionID, StartDato, SlutDato
På den måde har du en historik over tidligere funktioner
Du bør kigge lidt på stored procedures hvis du ikke har arbejdet med det før. SlutDato feltet skal være null som default.
eksempel på sql: CREATE Procedure UpdateFunk @FunktionID int, @MedarbejderID int, @StartDato Datetime, @SlutDato DateTime = null, @Medarbejder_FunktionID int output
AS BEGIN if EXISTS(SELECT 1 FROM Medarbejdere_i_Funktioner m WHERE m.MedarbejderID=@MedarbejderID AND m.FunktionID=@FunktionID AND getdate BETWEEN m.StartDato AND ISNULL(m.SlutDato,getdate()+1) ) BEGIN UPDATE m SET m.SlutDato=@StartDato-1 FROM Medarbejdere_i_Funktioner m WHERE m.MedarbejderID=@MedarbejderID AND m.FunktionID=@FunktionID AND getdate BETWEEN m.StartDato AND ISNULL(m.SlutDato,getdate()+1) END INSERT INTO Medarbejdere_i_Funktioner (MedarbejderID, FunktionID, StartDato, SlutDato) SELECT @MedarbejderID, @FunktionID, @StartDato, @SlutDato --hent nyt id SELECT @Medarbejder_FunktionID = SCOPE_IDENTITY()
Ved nærmere eftertanke tror jeg at jeg lige venter med det med start og slut dato. Men jeg vil forsøge at bygge det på senere...
Nu har jeg fået bygget database tabellerne. staff (indeholder personerne) functions (indeholder jobtyper) staffFunctions (sammenkobler de to)
Jeg har lavet en selectbox som indeholder alle jobtyperne fra tabellen functions. Når man vælger en jobtype viser den i et dataGrid hvilke staffId's der er tilknyttet netop denne functionsId. Men istedet for at vise "staffId" fra tabellen staffFunction (som sammenkobler de to tabeller) vil jeg jo gerne vise person navnene fra tabellen staff, som har de udvalgte staffId fra staffFunctions.
Du skal lave lidt joins i din select statement som så skal læse fra alle tre tabeller - dit andet forslag om at "skamfere" staffFunctions med redundant info er en af den slags short-cuts som dukker op senere og bider en i &%¤/&¤ :-)
Du kan faktisk lave et view som du kan selecte fra:
Create view view_staff_Functions AS SELECT s.staffid, s.name, f.functionname FROM staff s JOIN staffFunctions sf on sf.staffid=s.staffid JOIN functions f on f.functionid=sf.functionid
Så nu har jeg oprettet en tabel i databasen der hedder "bookingCalendar". Den indholder felterne "bookingId", "staffId" og "date"
Så nu har jeg er kalender modul hvor man kan vælge en dato og derefter en jobfunktion som man søger og så skal der i et gridview vises hvilke personer der IKKE er bookede på den dato man har valgt.
Så gridview'et skal altså unlade at vise de staffId's der har datoen tilknyttet i tabellen "bookingCalender"
Jeg har selv forsøgt lidt frem og tilbage med mit select statement, og mit bedste skud ser således ud: SELECT staff.staffName FROM staff INNER JOIN staffFunction ON staff.staffId = staffFunction.staffId CROSS JOIN bookingCalendar WHERE (staffFunction.functionId = @selectedFunction) AND (bookingCalendar.date <> @selectedDate)
men det virker desværre ikke helt. Er det helt skidt, eller er det blot en bagatel?
Jeg løber altid selv sur i joins, og plejer derfor at bruge den grafiske query-generator i Access (hvorpå jeg kan kopiere SQL-en direkte). har du ikke adgang til noget lignende i din SQL-frontend ?
Rent umiddelbart så synes der at mangle noget - men hæng mig ikke op på det: Jeg ville have forventet at bookingCalendar.staffId også skulle optræde på scenen et eller andet sted:) noget med bookingCalendar.staffId = staff.staffId - men det er måske fordi du har en cross join - og så får du formentligt for mange data. Du kunne bygge på det et skridt ad gangen : først lave en select som i stedet for staffName blot viser staffId korrekt (altså joined med bookingCalendar) - og derpå tilsætte staffname (og dermed også tabellen staff), når det forudgående funker.
Jo, der er også en query-builder i Visual Web Developer 2005, men jeg kan squ ikke rigtigt lige regne ud i hvilken rækkefølge det hele skal komme så der bliver rigtigt.
Så det der skal være tricket er, at hvis de allerede er booket på den dag, man har valgt i kalender-modulet, så må de ikke stå på listen over medarbejdere.
Jeg kan simpelthen ikke regne den ud. Men jeg synes i har hjulpet mig nok nu, så smid et svar så får i point. Og så opretter jeg en ny tråd med mit NYE problem, det er vel OK? Eller er det mog exp regler.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.