שאילתות מתקדמות

עמוד זה ממשיך את ההדרכה בנושא שאילתות וטעינת נתונים לטבלה.
בעמוד הקודם הוסברו הפקודות הבסיסיות: Clear, Load, Query, Where, LogicGate, Close_Query ו־Execute.
כאן נעסוק במנגנון מתקדם יותר: שמירת תוצאת שאילתה בשם זמני בצד השרת, ושימוש בתוצאה זו כדי לסנן שאילתה אחרת.

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

הערות:
  • כל הדוגמאות בעמוד זה מניחות שאתה כבר מכיר את מבנה העבודה הבסיסי: Reset, Query, Where, Close_Query ו־Execute.
  • בכל קריאת Query או Query_And_Remember יש להעביר את מאגר החיפוש במפורש, לדוגמה 'N', 'A' או 'NA'.
  • בכל קריאת Where יש להעביר LogicGate במפורש, לדוגמה he_AND או he_OR.
  • שם זיכרון (המוסבר בהמשך) חייב להיות שם חוקי ובאורך של 4 תווים לפחות.

Remember_Nickname - שמירת תוצאת Query לשימוש חוזר

הפרמטר Remember_Nickname (המכונה "שם זיכרון") הוא הפרמטר השלישי בפקודת Query.
הוא אינו חובה, אך כאשר מעבירים בו שם, השרת שומר אצלו את תוצאת ה־Query הנוכחי תחת אותו שם.
לאחר מכן ניתן להשתמש בשם הזה בשאילתה עוקבת, באמצעות Where_Included_In_Remembered_Query.

Server.Query(HTable: ThTable; Clear_On_Init: Boolean; Remember_Nickname: String; Attrib: String);

פרמטר הסבר יישום
HTable הטבלה המקומית שאליה ייטענו תוצאות השאילתה.
Clear_On_Init האם לנקות את הטבלה המקומית לפני הכנסת תוצאות השאילתה החדשה.
Remember_Nickname שם זיכרון (זמני) שבו השרת ישמור את תוצאת השאילתה.
אם אין צורך בשמירת תוצאת השאילתה, יש להעביר מחרוזת ריקה.
Attrib מאגר החיפוש, לדוגמה 'N', 'A' או 'NA'. חובה להעביר אותו במפורש.

כללים חשובים:
  • אם אין צורך בזיכרון שאילתה, יש להעביר מחרוזת ריקה בפרמטר השלישי של Query.
  • אם משתמשים בשם זיכרון, הוא חייב להיות שם חוקי ובאורך של 4 תווים לפחות.
  • השם משמש לזיהוי התוצאה בתוך מנגנון השאילתה בצד השרת, ואינו יוצר משתנה מקומי חדש בתסריט.
  • הזיכרון מיועד לשימוש בשאילתות נוספות שנשלחות באותה בקשת Execute.

דוגמה: טעינת לקוחות פעילים ושימוש בתוצאה לאיתור קריאות שירות.
בדוגמה זו השאילתה הראשונה גם טוענת את ClientsTb וגם שומרת את תוצאתה בשם Clients_Buf.
השאילתה השנייה טוענת קריאות שירות שמספרי הישות שלהן (Entity Number) נמצאים בתוצאת הזיכרון בהתאמה למפתח Client Number.
Server.Reset;

Server.Query(ClientsTb, True, 'Clients_Buf', 'N');
Server.Where_SameVal('Handling Status', 1, he_AND);
Server.Close_Query;

Server.Query(ServTicket, True, '', 'N');
Server.Where_Included_In_Remembered_Query('Entity Number', 'Clients_Buf', 'Client Number', he_AND);
Server.Close_Query;

IF NOT Server.Execute Then  EXIT;

הדרך הידנית ללא Remember_Nickname
ניתן לבצע את אותה פעולה גם ללא שם זיכרון, אך בדרך כלל הקוד יהיה ארוך יותר ופחות יעיל.
בדוגמה הידנית טוענים תחילה טבלת לקוחות זמנית, ואז מוסיפים לשאילתה השנייה תנאי Where עבור כל לקוח שנמצא.
VAR Clients_Buf: ThPrvTable;
    I: Integer;
Begin
  Clients_Buf:= Fman.Create_PrvTable('hyp_Clients', 'Clients_Buf', ['Client Number'], False);
  Clients_Buf.GlobalInit;

  // שאילתה ראשונה על מאגר הלקוחות
  Server.Reset;
  Server.Query(Clients_Buf, True, '', 'N');
  Server.Where_SameVal('Handling Status', 1, he_AND);
  Server.Close_Query;
  IF NOT Server.Execute Then  EXIT;

  IF Clients_Buf.Empty(0) Then Exit; // אם לא נמצאו תוצאות בשאילתה ראשונה - צא

  // שאילתה שנייה על מאגר קריאות השירות
  Server.Reset;
  Server.Query(ServTicket, True, '', 'N');
  For I:= 0 To Clients_Buf.RowCount-1 Do  // הוספת כל ערכי הלקוחות לאותה שאילתה בלולאה
    Server.Where_SameVal('Entity Number', Clients_Buf.IField['Client Number', I], he_AND);

  Server.Close_Query;
  IF NOT Server.Execute Then  EXIT;
End;

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

Where_Included_In_Remembered_Query - שימוש בתוצאת זיכרון

הפקודה Where_Included_In_Remembered_Query מוסיפה תנאי Where שמבוסס על תוצאה שנשמרה קודם בשם זיכרון.
במקום להעביר ידנית רשימת ערכים, מעבירים את שם הזיכרון ואת שם השדה שנשמר בתוצאה הקודמת.

Server.Where_Included_In_Remembered_Query(FieldName: String; From_Table_Nickname: String; From_Field_Name: String; LogicGate: Thds_Logic);
פרמטר הסבר יישום
FieldName שם השדה בשאילתה הנוכחית שאותו רוצים להשוות לתוצאת הזיכרון.
From_Table_Nickname שם הזיכרון שניתן לשאילתה קודמת.
From_Field_Name שם השדה מתוך תוצאת הזיכרון שמולו מתבצע החיפוש.
LogicGate אופן החיבור של התנאי לשאר תנאי ה־Where בשאילתה הנוכחית.
חובה להעביר אותו במפורש.

שים לב: From_Field_Name חייב להיות שדה שנכלל בתוצאה שנשמרה בזיכרון.
כאשר הזיכרון נוצר באמצעות Query רגיל על ThPrvTable, אלו שדות הבחירה של הטבלה הפרטית.
כאשר הזיכרון נוצר באמצעות Query_And_Remember, אלו השדות שהועברו בפרמטר SelectFields.

Query_And_Remember - שאילתה מקשרת ללא טעינה מקומית

כאשר צריך לבצע שאילתה שתלויה בתוצאה מטבלה אחרת, אך אין צורך לטעון את התוצאה הראשונה לטבלה מקומית, ניתן להשתמש ב־Query_And_Remember.
הפקודה מבצעת שאילתה לטבלה אחת ושומרת בזיכרון רשימת ערכים, שאפשר להשתמש בה לאחר מכן לסינון שאילתה אחרת.
בניגוד ל־Query רגיל עם Remember_Nickname, פקודה זו אינה מקבלת אובייקט ThTable ואינה טוענת טבלה מקומית.
היא מיועדת למצב שבו צריך רק לשמור שדות מסוימים מהשאילתה לצורך שאילתת המשך.

Server.Query_And_Remember(TableName: String; Remember_Nickname: String; SelectFields: ThFlds_Name_Array; Attrib: String);
פרמטר הסבר יישום
TableName שם טבלת מסד הנתונים שממנה מבצעים את השאילתה.
Remember_Nickname שם הזיכרון שבו תישמר תוצאת השאילתה.
השם חייב להיות חוקי ובאורך של 4 תווים לפחות.
SelectFields רשימת השדות שצריך לשמור בזיכרון לצורך שאילתות המשך.
מומלץ לשמור רק את השדות הדרושים בפועל, לדוגמה שדה מפתח או מספר ישות.
השמות חייבים להיות שמות שדות קיימים בטבלת המקור. לפי המימוש בקוד, רק שדות שנמצאו בטבלה נכנסים לרשימת ה־Select שנשלחת לשרת.
Attrib מאגר החיפוש, לדוגמה 'N', 'A' או 'NA'. חובה להעביר אותו במפורש.

מתי להשתמש ב־Query_And_Remember
  • כאשר תוצאת השאילתה הראשונה נדרשת רק כמסנן לשאילתה אחרת.
  • כאשר אין צורך להציג או לעבד את תוצאת השאילתה הראשונה בתוך התסריט.
  • כאשר רוצים לצמצם טעינה של טבלאות מקומיות ולהעביר לשרת רק את הקשר בין השאילתות.

דוגמה: מציאת לקוחות לפי שם איש קשר.
Server.Reset;

Server.Query_And_Remember('hyp_Client Contacts', 'Contact_Buf', ['File Number'], 'N');
Server.Where_String_Search('Contact Full Name', 'David', he_AND);
Server.Close_Query;

Server.Query(ClientsTb, True, '', 'N');
Server.Where_Included_In_Remembered_Query('Client Number', 'Contact_Buf', 'File Number', he_AND);
Server.Close_Query;

IF NOT Server.Execute Then  EXIT;

בדוגמה זו, השאילתה הראשונה מוצאת אנשי קשר שבשם שלהם קיימת המחרוזת "David" ושומרת את מספרי הישות שלהם בזיכרון.
השאילתה השנייה טוענת את הלקוחות שמספר הלקוח שלהם קיים בזיכרון מהשאילתה הקודמת.
הפרמטר 'File Number' ב־Where_Included_In_Remembered_Query חייב להתאים לשדה שנשמר ב־SelectFields של Query_And_Remember.

ההבדל בין Query עם Remember_Nickname לבין Query_And_Remember

שתי הדרכים שומרות תוצאה בשם זיכרון בצד השרת, אך הן מיועדות למצבים שונים.

אפשרות מה היא עושה מתי להשתמש
Query עם Remember_Nickname טוענת תוצאה לטבלה מקומית וגם שומרת את אותה תוצאה בשם זיכרון. כאשר צריך גם להשתמש בנתונים בתסריט וגם להשתמש בהם כמסנן לשאילתה נוספת.
Query_And_Remember שומרת בצד השרת רק את השדות שנבחרו, ללא טעינת טבלה מקומית. כאשר התוצאה הראשונה נדרשת רק לצורך שאילתת המשך.

כלל אצבע: אם אתה צריך לקרוא את הנתונים בתסריט עצמו, השתמש ב־Query עם Remember_Nickname.
אם הנתונים נדרשים רק כדי לסנן שאילתה אחרת, השתמש ב־Query_And_Remember.

טעויות נפוצות בשאילתות מקשרות

  • שימוש בשם זיכרון קצר מדי. שם הזיכרון חייב להיות באורך של 4 תווים לפחות.
  • שימוש בשם זיכרון שונה בין השאילתה ששומרת את התוצאה לבין השאילתה שמשתמשת בה.
  • העברת From_Field_Name שאינו נמצא בתוצאה שנשמרה בזיכרון.
  • העברת שדה לא קיים בתוך SelectFields של Query_And_Remember.
  • השמטת LogicGate מקריאת Where_Included_In_Remembered_Query.
  • השמטת Attrib מקריאת Query או Query_And_Remember.