העיקרון בפורום הוא שיש הודעת אב ולה יש הודעות ילדים. הודעות האב מסודרות בסדר כרונולוגי הפוך והודעות הילדים מסודרות ביניהם לפי סדר יורד. אבל בואו נתחיל מהתחלה. בד"כ אני נוהג לצייר לי סכמה של התהליך ושל הטפסים על מנת שיהיה לי יותר קל אח"כ להבין מה עשיתי. דבר ראשון - הקמת הDB. קודם כל אני אבנה את הטבלה של המשתמשים הדברים החשובים ביותר הם: שם משתמש [כינוי], סיסמא , אמייל , ורצוי גם תאריך. אני הוספתי עוד כמה שדות לשימושי האישי. אני אקרא לה members
|
שם שדה |
סוג DATATYPE |
תפקיד |
ערך ראשוני |
|
Id |
מספור אוטומטי |
מפתח ראשי |
|
|
UserID |
מספר |
המספר של המשתמש |
|
|
Nick |
מחרוזת |
הכינוי |
|
|
Pass |
מחרוזת |
הסיסמא |
|
|
Email |
מחרוזת |
אימייל |
|
|
DateAdd |
|
תאריך הוספה |
Date() |
|
Fname |
מחרוזת |
שם פרטי |
|
|
Lname |
מחרוזת |
שם משפחה |
|
|
Address |
מחרוזת |
כתובת |
|
|
Sex |
כן/לא |
זכר/נקבה |
|
|
Qut |
מחרוזת |
ציטוט |
|
|
WordDes |
תזכיר |
תיאור עצמי |
|
|
Homepage |
מחרוזת |
הטקסט שיופיע כדף בית |
|
|
Link |
מחרוזת |
הקישור לדף הבית |
|
|
Age |
מספר |
הגיל |
|
השלב הבא הוא לבנות את הטבלה של ההודעות. אצלי היא בפורמט הבא:
|
שם שדה |
סוג DATATYPE |
תפקיד |
ערך ראשוני |
|
MessageID |
מספור אוטומטי |
מפתח ראשי |
|
|
ForumID |
מספר |
מספר הפורום |
|
|
Parented |
מספר |
המספר של הודעת האב |
|
|
levelID |
מספר |
מה הסדר של ההודעות |
|
|
MsgSubject |
מחרוזת |
הנושא |
|
|
MassegeBody |
מחרוזת |
גוף ההודעה |
|
|
Uname |
מחרוזת |
הכינוי |
|
|
Uid |
מספר |
המספר של המשתמש |
|
|
link1 |
מחרוזת |
קישורים |
|
|
Link1des |
מחרוזת |
הטקסט שיוציע |
|
|
IsFile |
כן/לא |
האם יש קבצים מצורפים |
|
|
Filename |
מחרוזת |
שם הקובץ |
|
|
fileDES |
מחרוזת |
תיאור של הקובץ |
|
|
DateAdd |
תאריך |
תאריך הוספה |
Date() |
ניתן כמובן להוסיף עוד קישורים ותאורי קישורים [ורצוי גם לחלק את הטבלה לשתי טבלאות של קבצים ושאר הודעות ולחבר העזרת הMASSEGEID ...] אבל בינתיים זה מספיק. אה, כן ניקרא לה masseges.
בעיות
בעיה ראשונה: איך יודעים מהי הודעת האב ? מכיון שלכל הודעה חדשה אנו צריכים מספור כלשהו. עומדות לפנינו כמה אפשרויות. האפשרות הראשונה היא להכניס איזה שהוא מספור שאנחנו יוצרים לתוך ה parentID. החיסרון בשיטה הזו היא שאם יש לנו כמה משתמשים בו זמנית אנו עלולים להרוס את הסדר. הפתרון הפשוט ביותר הוא להשתמש במשתנה Session.SessionID ולהכניס אותו לתוך הודעת האב. לכל הבנים שיבואו מתחתיו אנו ניתן כבר את ה parentID הקיים, וניתן levelID שגדל באחד כל פעם. [רצוי להתחיל ב1 ולא ב0] לאחר שנוסיף את ההודעה נסגור את ה Session ונחליף אותה בחדשה בעזרת Session.Abandon(). ככה אני פותר שתי בעיות - אין לי בעיית מספור וגם לא בעיית הכנסה, כי לכל משתמש יש מספר מזהה משלו, ואין שום סיכוי שבעולם ששני אנשים שונים יכניסו שתי הודעות עם אותו parentID . אם הייתי ממספר את ההודעות בזמן ההכנסה היה לי סיכוי שתקרה התקלה הזו.
בעיה שנייה - אם יש לי שתי הודעות בן לאותו - מי תבוא קודם? זאת שנכתבה קודם כמובן ואת זה נדע לפי השדה של התאריך. ועכשו איך עושים את זה?
בעייה שלישית - איך לעזאזל אני עושה את ההזחה של ההודעות? בעזרת ה levelID. כל הודעה תהייה טבלה בפני עצמה שהרוחב שלה הוא ה100% מינוס ה levelID. כל זה יהיה באחוזים ומיושר לשמאל ככה שתהייה לי הזחה כל הודעה. טוב עכשו איך עושים את זה? עכשו יש כל מני דרכים לשלוף את הנתונים מתוך ה DB. מכיוון שזה עץ ניתן לשלוף את הנתונים בעזרת DATASHAPE, או בעזרת שני recordSet , או לעשות איזה עמודת מונה שתסדר לי את ההודעות. עם recordSet הכפול הייתי עושה משהו כזה :
DSN="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Server.MapPath("theBD.mdb") +";"
SQL1="select parentID from masseges where levelID=1 order by dateAdd DESC"
SQL2=""select * from masseges where parentID="& oRss(0).value & "order by levelID;"
Set oConnection=Server.CreateObject("ADODB.connection")
OConnection.open (DSb)
Set oRecordset==Server.CreateObject("ADODB. Recordset")
ORecordset.open (SQL1, oConnection,3,1)
While not oRecordset.eof
ORecordsetMasege=oConection.execute(SQL2)
While not OrecordsetMasege.eof
'כאן תיכנס הטבלה של כל הודעה והודעה
OrecordsetMasege.movenext()
Wend
ORecordset.movenext()
Wend
איך זה עובד? בהתחלה אנו שולפים את כל הרשומות שה parentID שלהם הוא 1 - כלומר הן הודעות אב. אח"כ אנו בלולאה השנייה אנו שולפים לכל הודעת אב את הבנים שלה, מסודרים לפי ה levelID. אבל השיטה הזאת לא יעילה וממש לא נוחה. אם הייתי יכול להכניס איזה ממספר שהיה עוזר לי למיין את כולם מצבי היה יותר טוב. השיטה הטובה ביותר לממספר שחשבתי עליה היא מן מחרוזת שהחלק השמאלי שלה מורכב מה ParentID והחלק הימני ה levelID. אבל למה לעבוד קשה? למה אני צריך להתאמץ לסדר את ההודעות כאשר אני יכול להשתמש ב DB למיון וסידור ההודעות. לא רק זה אפילו יש לי WIZARD שעושה את כל העבודה השחורה. אם ניסתכל על הטבלה שלנו [וגם כל הקוד שרשמנו מקודם ] נוכל לראות שבעצם יש לנו המון כפילויות בעמודה של ה parentID. ופה קבור הכלב! נפתח את האקסס [או כל DB אחר אבל זה יהיה בלי ה WIZARD...] נלך לשאילתות ונבחר את השאילתא הבאה - שאילתת חיפוש כפילויות.

נלחץ על אישור ובחלון הבא נבחר את הטבלה שלנו masseges .

לחיצה על הבא כמובן תוביל אותי לשאלה - איזה עמודה אני רוצה לסנן? parentID כמובן תהייה התשובה . לא לשכוח ללחוץ "הבא" אחר כך.

עכשו בא הקטע המגניב - איזה עוד שדות אני רוצה בשאילתא שלי . את כל השאר.

אני אתן שם לשאילתא ואלחץ על סיום.

עכשו כשאני אפתח את הטבלה/ שאילתא חדשה אני אקבל טובלה ממש דומה דMASSEGES אולם זה עדיין לא הסוף. אני עדיין צריך למיין את הכל. תצוגת העיצוב תיתן לי את התמונה הבאה. השתמשו בגרירות השונות על מנת להביא את הטבלה למצב הקיים ושנו את הסדר לפי התמונה.

כאשר נפעיל את השאילתא נקבל את הטבלה ממויינת. כל מה שאנחנו צריכים לעשות עכשו הוא לשלוף את הנתונים. היתרון בשיטה זו היא שאנו שולפים את הנתונים מתוך שאילתא אך מכניסים אותה לתוך הטבלה. הנתונים תמיד יהיו ממוינים, ללא צורך באיזה שהוא טרנספורמציה על העמודה המסדרת [שבעצם לא קיימת]. למעשה אם היינו צריכים ליצור את השאילתא הזו ביד זה היה משהו כזה SELECT massege.parentID, massege.dateAdd, massege.levelID,
massege.messageID, massege.forumID, massege.Uname, massege.Uid, massege.msgSubject,
massege.link1, massege.Link1des, massege.link2, massege.Link2des, massege.link3,
massege.Link3des, massege.isFile, massege.IP, massege.fileName, massege.fileDES
FROM massege
WHERE (((massege.parentID) In (SELECT [parentID] FROM [massege] As Tmp GROUP
BY [parentID] HAVING Count(*)>1 )))
ORDER BY massege.parentID DESC , massege.dateAdd, massege.levelID;
לא סימפטי אה? בדיוק בשביל זה יש לנו QUERY אנליזר. עכשו הכל כבר מסודר וכל מה שנשאר זה לשלוף את הכל בעזרת Select * from ForumMSG.
ואם יש כמה פורומים פשוט לשים WHERE... איפה שצריך. עכשו הASP שלי ניראה ככה
DSN="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Server.MapPath ("theBD.mdb")
+";User Id=admin; Password="
SQL1=" Select * from ForumMSG.
Set oConnection=Server.CreateObject("ADODB.connection")
OConnection.open (DSN)
Set oRecordset==Server.CreateObject("ADODB. Recordset")
ORecordset.open (SQL1, oConnection,3,1)
While not oRecordset.eof
כאן תיכנס הטבלה של כל הודעה והודעה
oRecordset.movenext()
Wend
|