דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. עבודה עם ריבוי תוצאות MySQL מתוך Asterisk

עבודה עם ריבוי תוצאות MySQL מתוך Asterisk

מתוזמן נעוץ נעול הועבר תכנות
11 פוסטים 3 כותבים 962 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • איש אחדא מנותק
    איש אחדא מנותק
    איש אחד
    כתב ב נערך לאחרונה על ידי איש אחד
    #1

    בס"ד

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

    אני ניגש למסד MySQL ישירות מתוך ה DialPlan של אסטריסק באמצעות הפקודה MySQL.
    הביצוע של השאילתות שליפה / הוספה / עדכון עובד בסדר גמור*.

    *אבל, כאשר אני מבצע שאילתת שליפה שאמורה להחזיר יותר מתוצאה אחת,
    לדוגמא: שליפה של כל המוצרים שמשוייכים לקטגוריה X,
    המאפיין "Fetch" שמכניס את התוצאות למשתנים - מכניס רק את ההתאמה (השורה) הראשונה,
    ואם אני חוזר שוב על ה "Fetch" הוא מכניס רק את השניה וכן הלאה,
    עד ההתאמה האחרונה, ואז חזרה נוספת על ה "Fetch" תוציא שגיאה.

    השאלה שלי,
    איך אני יכול לדעת כמה תוצאות אמורות להיות,
    ובעיקר, איך אני מנווט בין התוצאות קדימה ואחורה או "תופס" התאמה ספציפית (לדוגמא, 4).

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

    האם מישהו יודע על דרך נורמלית לטייל בין ההתאמות שהתקבלו?

    תודה רבה!!!

    clickoneC תגובה 1 תגובה אחרונה
    1
    • dovidD מנותק
      dovidD מנותק
      dovid ניהול
      כתב ב נערך לאחרונה על ידי dovid
      #2

      יש פה איזה תכנון שלא הכי מריח לי, אבל נתחיל בזה שfetch קורא ישר מהזרם שמגיע מהDB ולכן לא שייך בו אחורה, וגם כדאי "לגמור איתו" כמה שיותר מהר כדי לנקות את הקונקשיין.
      בשביל לטייל אחורה על כרחך אתה צריך לשים את התוצאות במערך, שכל שלב אתה מוסיך איבר, עד לשלב בו הfetch מחזיר null.
      איך עושים מערך ואיך מנווטים בו בחיה הזו? אין לי מושג ואני נורא מעריך את מתכנתי העל שמבינים את שפת החרטומים הזו.

      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

      בכל נושא אפשר ליצור קשר dovid@tchumim.com

      איש אחדא תגובה 1 תגובה אחרונה
      3
      • clickoneC מנותק
        clickoneC מנותק
        clickone
        השיב לאיש אחד ב נערך לאחרונה על ידי clickone
        #3

        @איש-אחד זה dialplan קלאסי?
        למה שלא תשתמש בphpagi הרבה הרבה יותר הגיוני ופשוט.

        דוגמא:
        https://www.voip-info.org/asterisk-simple-php-lookup-mysql-database-to-set-callerid-name/

        עוד דוגמא

        #!/usr/bin/env php
        
        
        <?php
        //echo "run";
          set_time_limit(30);
          require('phpagi.php');
          error_reporting(E_ALL);
          $agi = new AGI();
          $agi->answer();
        $cid = $agi->parse_callerid();
        //$agi->say_number("$cid"); // speaks the number 1234
        
          fwrite(STDOUT, "NOOP $cid ");
          fflush($agi);
        $ani = $agi->request['agi_callerid'];
         $agi->noop("My CalleID: <<<<<<<=".$ani);
        $agi->say_digits("1234")
        //  fwrite(STDOUT, "SAY DIGITS 5551212 '125#'");
        //  fflush($agi);
        
        //saynumber("1234");
        //  $agi->text2wav('Goodbye');
        //$agi->stream_file('vm-isunavail.gsm');
        //$agi->say_number("0548486354"); // speaks the number 1234
        
          $agi->hangup();
        ?>
        
        

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

        אם אתה צריך עזרה בזה אז תכתוב כאן

        עריכה: @איש-אחד סורי שעד שלחצתי "שלח" הספקת לכתוב את המגילה... 🙂
        זה היה כתוב כבר ממזמן. רק שכחתי ללחוץ שלח... 😞

        אין טסט כמו פרודקשן.

        המייל שלי urivpn@gmail.com

        תגובה 1 תגובה אחרונה
        2
        • איש אחדא מנותק
          איש אחדא מנותק
          איש אחד
          השיב לdovid ב נערך לאחרונה על ידי
          #4

          @dovid
          תודה על התשובה!

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

          מה גם, שלפעמים אני רוצה שאילתא גדולה, למשל, שישמיע את כל ה"מוצרים" (שורות בטבלה) אחד אחרי השני.
          ולהעתיק את כל הדטהבייס קומפלט לתוך המערך - נראה לי לא יותר מידי פרקטי.

          עלה לי עכשיו רעיון, ואשמח לשמוע עליו ביקורת - אם מגיע לו כזאת,
          כשאני כותב שאילתא, להוסיף לה LIMIT 0,2, דהיינו שישלוף עד 2 התאמות, ויתחיל מההתאמה הראשונה,
          כשהערך 0 שממנו מתחילים לקבל את ההתאמות, יתקבל מתוך משתנה.
          לאחר ביצוע השאילתא אני עושה סיבוב ראשון של ה "Fetch" כרגיל ומקבל את כל הערכים,
          ואז אני עושה עוד סיבוב אחד של "Fetch" - רק בשביל לוודא שהוא לא NULL (דהיינו, שקיימות התאמות נוספות).
          במידה ואכן קיימות התאמות נוספות,
          כשאבקש לזוז קדימה / אחורה - אעדכן בהתאם את המשתנה שממנו ה LIMIT מתחיל להחזיר תוצאות,
          ופשוט אבצע את השאילתא שוב, כשהפעם ה LIMIT מתחיל לשלוף את 2 ההתאמות מ -1 במקום מ - 0, וכן הלאה.

          מה אתם אומרים?

          תגובה 1 תגובה אחרונה
          3
          • dovidD מנותק
            dovidD מנותק
            dovid ניהול
            כתב ב נערך לאחרונה על ידי dovid
            #5

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

            שים לב שבדוגמה הרשמית שלהם יש לולאה, כזו:

            exten => 888,n(fetchrow),MYSQL(Fetch foundRow ${resultid} number) ; fetch row
            exten => 888,n,GotoIf($[“${foundRow}” = “1”]?done) ; leave loop if no row found
            exten => 888,n,NoOp(${number})
            exten => 888,n,Goto(fetchrow) ; continue loop if row found
            exten => 888,n(done),MYSQL(Clear ${resultid})
            

            בעיקרון כל שפת תכנות בעולם נראית בlow level ככה, אז גם אתה עם קצת ראש יכול להפיק מזה הכל.
            למשל במקרה שלך תוכל לשים כל פעם את התוצאה של השורה הקודמת במשתנה בשם previusrow ולבדוק אותו.

            מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

            בכל נושא אפשר ליצור קשר dovid@tchumim.com

            איש אחדא תגובה 1 תגובה אחרונה
            2
            • איש אחדא מנותק
              איש אחדא מנותק
              איש אחד
              השיב לdovid ב נערך לאחרונה על ידי איש אחד
              #6

              @dovid
              בחישוב ביצועים אני לא מבין בכלל, תודה שהמלצת על דרך יותר טובה!
              ו @clickone , תודה רבה גם על העזרה כאן וגם "מאחורי הקלעים"!

              אגב, בדוגמא שציטטת (@dovid),
              היא רק ממחישה את הבעייה שלי - חוסר יכולת בניווט קדימה אחורה.
              מה שקורה שם, זה בשורה הראשונה ה Fetch שומר את התוצאה במשתנה בשם number,
              בשורה השלישית הוא רושם אותו בפלט של האסטריסק (ובקבצי הלוג),
              ובשורה הרביעית הוא מחזיר בלופ לשורה הראשונה שבתורה דורסת את number בלי שום נקיפות מצפון...

              dovidD תגובה 1 תגובה אחרונה
              2
              • dovidD מנותק
                dovidD מנותק
                dovid ניהול
                השיב לאיש אחד ב נערך לאחרונה על ידי
                #7

                @איש-אחד אמר בעבודה עם ריבוי תוצאות MySQL מתוך Asterisk:

                אגב, בדוגמא שציטטת (@dovid),
                היא רק ממחישה את הבעייה שלי - חוסר יכולת בניווט קדימה אחורה.
                מה שקורה שם, זה בשורה הראשונה ה Fetch שומר את התוצאה במשתנה בשם number,
                בשורה השלישית הוא רושם אותו בפלט של האסטריסק (ובקבצי הלוג),
                ובשורה הרביעית הוא מחזיר בלופ לשורה הראשונה שבתורה דורסת את number בלי שום נקיפות מצפון...

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

                מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                בכל נושא אפשר ליצור קשר dovid@tchumim.com

                איש אחדא תגובה 1 תגובה אחרונה
                1
                • איש אחדא מנותק
                  איש אחדא מנותק
                  איש אחד
                  השיב לdovid ב נערך לאחרונה על ידי
                  #8

                  @dovid
                  נניח יש לי מערכת מכירות טלפונית עם כמות מוצרים לא קבועה,
                  ואני רוצה לאפשר למתקשר פשוט לשמוע את כל המוצרים לפי סדר.

                  אני נותן שאילתא של SELECT * FROM table,
                  כל הטבלה קומפלט נכנסת לתוך משתנה בשם result נניח,
                  ואז ה Fetch עושה Parse רק לשורה הראשונה ומפריד את העמודות לתוך משתנים, לדוגמא: שם מוצר, קוד, מחיר וכדו'.
                  אני משמיע למתקשר את תכולת המשתנים שהתקבלה.
                  זהו הוא שמע. עכשיו הוא בוחר נניח ב: "למעבר למוצר הבא, הקישו X". מה אני עושה איתו?
                  אז למעשה, אם אני חוזר שוב פעם על אותה פעולת Fetch בדיוק בלי שום שינוי -
                  הוא ידרוס את הערכים הקודמים של שורה 1 ששמורים במשתנים, ובמקומם יכניס את הערכים של שורה 2.
                  טוב. המתקשר שמע את גם את שורה 2.
                  אבל הפעם המתקשר החליט לאתגר אותי ובחר ב: "לחזרה למוצר הקודם, הקישו X".
                  מה אני עושה איתו עכשיו?

                  dovidD תגובה 1 תגובה אחרונה
                  1
                  • dovidD מנותק
                    dovidD מנותק
                    dovid ניהול
                    השיב לאיש אחד ב נערך לאחרונה על ידי dovid
                    #9

                    @איש-אחד
                    אם זה המקרה זה לוגיקה של דפדפוף אלא דפדוף לשם דיפדוף. לזה אין לי פתרון.

                    אגב, ההבנה שלך שfetch סה"כ מפרסר רשומה מresult שגויה לדעתי.
                    בresult אין את הטבלה רק buffer - כלומר גוש הנתונים הבא. אם למשל אתה מתשאל 20,000 שורות
                    אתה יכול לראות שבזכות הfetch (שזה נקרא בכלל השפות forward-only cursor) הזיכרון ייראה בדיוק אותו דבר כמו עם אלף שורות.
                    מאותה סיבה גם אסור לסגור את הקונקשיין בטרם יתבצע הfetch האחרון.

                    מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                    בכל נושא אפשר ליצור קשר dovid@tchumim.com

                    תגובה 1 תגובה אחרונה
                    2
                    • איש אחדא מנותק
                      איש אחדא מנותק
                      איש אחד
                      כתב ב נערך לאחרונה על ידי
                      #10

                      מעניין לעניין באותו עניין,

                      מה באמת כדאי - לגבי סגירת קונקשן,

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

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

                      תודה רבה!

                      תגובה 1 תגובה אחרונה
                      1
                      • dovidD מנותק
                        dovidD מנותק
                        dovid ניהול
                        כתב ב נערך לאחרונה על ידי
                        #11

                        לדעתי תפתח ותסגור כל שאילתה, וגם תעשה שאילתה ממש לכל צעד.

                        מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                        בכל נושא אפשר ליצור קשר dovid@tchumim.com

                        תגובה 1 תגובה אחרונה
                        2

                        בא תתחבר לדף היומי!
                        • התחברות

                        • אין לך חשבון עדיין? הרשמה

                        • התחברו או הירשמו כדי לחפש.
                        • פוסט ראשון
                          פוסט אחרון
                        0
                        • דף הבית
                        • קטגוריות
                        • פוסטים אחרונים
                        • משתמשים
                        • חיפוש
                        • חוקי הפורום