יצוא דו"ח ל-CSV

פורומים אפיון ופיתוח פריוריטי יצוא דו"ח ל-CSV

  • Post
    שפרה הדסי
    משתתף
    שלום,

    בניתי ד"וח פרטי במערכת, וכעת ישנן מספר דרישות נוספות שאני לא יודעת איך לבצע:

    1.יש לייצא את הדו"ח ל- CSV format with comma-delimited and double-quote escape if needed

    2. מרגע יצוא הקובץ, לא ניתן יהיה לבצע שינויים כלל

    למישהו יש מושג איך עושים זאת?

    תודה,
    שפרה

מוצגות 15 תגובות – 1 עד 15 (מתוך 16 סה״כ)
  • Replies
    אלמוני
    אורח
    CSV = COMMA SEPARATED VALUES
    דהיינו ערכים שמופרדים באמצעות פסיק
    ניתן לבנות קובץ כזה בקלות יחסית באמצעות פרוצדורה.
    1. בתחילת הפרודצורה, תוסיפי את השורות

    :NOTABSTITLE = :HEBREWFILTER = 1;
    :FNAME = 'R:\OUTPUT.TMP';

    2. תבצעי את השליפה ממסד הנתונים כאשר השאילתא מסתיימת בשתי מילים קריטיות. נניח משהו כזה
    SELECT CUSTOMERS.CUSTNAME, CUSTOMERS.CUSTDES
    FROM CUSTOMERS
    TABS :FNAME
    ;

    3. לאחר היווצרות הקובץ הזה, נדרשות עוד כמה פקודות

    :CNAME = 'X:\OUTPUT.CSV';
    EXECUTE FILTER '09', '09', '44', :FNAME, :CNAME;
    EXECUTE DELWINDOW 'f', :FNAME

    ;

    פקודת ה-FILTER מענינת: הקובץ המקורי נוצר עם טאבים בין השדות והפקודה הזו הופכת את הטאבים לפסיקים. ב-ASCII, טאב = 09 ופסיק = 44.
    הפקודה האחרונה מוחקת את הקובץ הזמני.

    לגבי double-quote escape if needed, למבנה CSV יש בעיה אם בנתונים עצמם יש פסיק. סביר להניח שלא יהיה במספר הלקוח אך שם הלקוח בהחלט יכול להכיל פסיק. כדי להתגבר על כך, צריך "לעטוף" אם השם באמצעות גרשיים, בצורה כזו

    STRCAT ('"', CUSTOMERS.CUSTDES, '"')

    דהיינו סוגר, גרש, גרשיים, גרש, פסיק, CUSTOMERS.CUSTDES, פסיק, גרש, גרשיים, גרש, סוגר.

    מקווה שזה עוזר B)

    שפרה הדסי
    משתתף
    יש סיכוי טוב שזה עוזר, אבל זה הרבה הרבה מעבר לידע שלי 🙂

    תודה בכל מקרה!!

    אלמוני
    אורח
    בס"ד

    תודה רבה ,
    האם אפשר שגם הכותרות יהיו בשורה הראשונה של הקובץ ?

    תודה , משה

    אלמוני
    אורח
    בס"ד

    תודה רבה ,
    האם אפשר שגם הכותרות יהיו בשורה הראשונה של הקובץ ?

    תודה , משה

    אלמוני
    אורח
    אני לא בטוח, אבל אפשר לנסות כך.
    בהתחלה, צריך לכתוב את שם התכנית אל קובץ הפלט, תוך כדי שימוש בפקודה ADDTO
    select 'name of report' from dummy addto :fname

    אחר כך, במשפט השליפה, צריך להוסיף את ADDTO בין המלה TABS לבין FNAME

    אלמוני
    אורח
    בס"ד

    ראשית ממש תודה רבה ,
    אך לצערי לא הסכים לתחביר של השאילת שליפה
    SELECT CELL FROM TABLE
    ORDER BY FAMILYNAME
    TABS ADDTO :FNAME;

    זורק שגיאה על ה
    addto

    יש לכם אולי רעיון אחר ?

    בברכה משה

    אלמוני
    אורח
    הסתכלתי ב-SDK לפני שכתבתי את התשובה. קיבלתי את הרושם שניתן לכתוב גם TABS וגם ADDTO אך כנראה לא.

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

    אלמוני
    אורח
    בס"ד

    תודה רבה ,

    האם יש אפשרות לעשות union בשאילתה
    כלומר בסגנון הזה :

    SELECT firstName, lastName, company FROM businessContacts
    UNION
    SELECT firstName, lastName, NULL FROM nonBusinessContacts

    אלמוני
    אורח
    בדיקה מהירה ב-WINDBI מגלה שלא ניתן להשתמש בפקודה הסטנדרטית UNION

    דרך נוספת שעולה לי לראש:
    1. תיצור קובץ מלונקק ל-STACK4
    2. תכניס ל-STACK4 רשומה, כאשר KEY = 1 ו-DETAILS = כותרת הדו"ח
    3. תשלוף את הנתונים שאתה רוצה לתוך שדות ב-STACK4, כאשר KEY = SQL.LINE + 1
    4. תשלוף את הערכים שזה עתה הכנסת לטבלה STACK4 אל קובץ הפלט, כפי שכתבתי קודם

    אלמוני
    אורח
    בסד
    בוקר טוב, מה זה קובץ מלונקק וכן
    Stack4

    בתודה מראש על כל העזרה!
    משה

    אלמוני
    אורח
    :NOTABSTITLE = :HEBREWFILTER = 1;
    :FNAME = 'R:\OUTPUT.TMP';
    SELECT SQL.TMPFILE INTO :TMP FROM DUMMY;
    LINK STACK4 TO :TMP;
    INSERT INTO STACK4 (KEY, INTDATA, DETAILS)
    VALUES (1, 0, 'PROCEDURE NAME');
    INSERT INTO STACK4 (KEY, INTDATA)
    SELECT SQL.LINE + 1, CUSTOMERS.CUST
    FROM CUSTOMERS
    WHERE CUSTOMERS.CUSTSTAT = -3;
    SELECT CUSTOMERS.CUSTNAME, CUSTOMERS.CUSTDES, STACK4.DETAILS
    FROM STACK4, CUSTOMERS
    WHERE STACK4.INTDATA = CUSTOMERS.CUST
    TABS :FNAME;
    :CNAME = 'X:\OUTPUT.CSV';
    EXECUTE FILTER '09', '09', '44', :FNAME, :CNAME;
    EXECUTE DELWINDOW 'f', :FNAME
    UNLINK AND REMOVE STACK4

    בשורות 3 ו-4 יוצרים טבלה זמנית (בלשון חברות המישמות, טבלה מלונקקת).

    אלמוני
    אורח
    בס"ד

    ראשית שוב תודה רבה על כל ההשקעה
    לצערי לא הצלחתי כמו שאמרת זה נתן כותרת אחת ולא תחת השדה של הנתון

    אבל ב"ה מצאתי פתרון לכל מי שרוצה הקמנו curor וכך זה באמת סיפק את הסחורה

    :FNAME = 'C:\TEMP\OUTPUT.TMP';
    :CNAME = 'C:\TEMP\OUTPUT.CSV';
    EXECUTE DELWINDOW 'f', :CNAME ;
    SELECT 'כותרת1' , ',' , 'כותרת2' FROM DUMMY ASCII ADDTO :CNAME ;
    DECLARE C CURSOR FOR
    SELECT CUSTNAME , CUSTDES
    FROM CUSTOMERS;
    OPEN C;
    GOTO 9 WHERE :RETVAL = 0;
    LABEL 1;
    FETCH C INTO :CUR1 , :CUR2;
    GOTO 8 WHERE :RETVAL = 0; /* No more fetched records */
    SELECT :CUR1 , ',' , :CUR2 FROM DUMMY ASCII ADDTO :CNAME ;
    LOOP 1;
    LABEL 8;
    CLOSE C;
    LABEL 9;
    END;

    יש הסבר ב sdk
    שוב תודה רבה ושבת שלום .

    אלמוני
    אורח
    בס"ד

    שלום רב ,

    אתם יודעים אזה סמן אני צריך לשרשר בסוף כל שורה בקובץ csv
    בכדי שירד שורה כלומר ,כאשר פותח באקסל זה יורד שורה
    אך יש לנו תוכנה שכאשר נותן לה את CSV שיצרנו היא לא מצליחה לזהות ירידת שורה

    אשמח לכל עזרה ושוב תודה רבה

    אלמוני
    אורח
    התקלה נובעת מכך שהשתמש בפקןדה ASCII במקום TABS, כפי שהיה בדוגמא המקורית. שימוש ב-TABS גורם לכך שכל רשומה מופיעה בשורה נפרדת, כאשר כל שדה ברשומה מופרד ב-TAB. התכנית המקורית השתמשה בתכנית החיצונית FILTER להפוך את הטאבים הללו לפסיקים.

    השימוש ב-ASCII – כפי שגילית – גורם לרצף, ללא הפרדה בין ההשדות ולבין הרשומות. ארשום למטה פרוצדורה שיודעת להוציא את המלל של כל שלבי SQLI בפרוצדורה לקובץ טקסט. התכנית שימושית בעצמה אך היא גם מראה איך ניתן להתגבר על הבעייה שציינת – שכבר לא שייכת לנושא קבצי CSV!


    /* GLOB_PROGTEXTFILE - No'am, 26/07/15
    This procedure reads the SQLI/INPUT/INPUTF stages of a procedure and
    outputs the lines to a text file
    */
    :SPECIAL_CHARACTER = '\0';
    :SPECIAL_CHARACTER = '^';
    :SC = ITOA (0 + :SPECIAL_CHARACTER);
    :FNAME = 'OUTPUT.TXT';
    :EXEC = 0;
    :ENAME = '';
    LINK EXEC TO :$.EXE;
    ERRMSG 1 WHERE :RETVAL 0
    AND TYPE = 'P';
    ERRMSG 2 WHERE :EXEC 1;
    SELECT EXEC, ENAME INTO :EXEC, :ENAME
    FROM EXEC
    WHERE EXEC > 0
    AND TYPE = 'P';
    UNLINK EXEC
    ;
    DECLARE CUR CURSOR FOR
    SELECT PROGRAMS.POS, PROGRAMS.PROG, EXEC.ENAME
    FROM PROGRAMS, EXEC
    WHERE PROGRAMS.EXEC = :EXEC
    AND PROGRAMS.EXECRUN = EXEC.EXEC
    AND EXEC.ENAME IN ('SQLI', 'INPUT', 'INPUTF')
    AND PROGRAMS.PROG > 0;
    OPEN CUR;
    GOTO 500 WHERE :RETVAL <= 0;
    SELECT 'Program Name: ', :ENAME, :SPECIAL_CHARACTER FROM DUMMY
    ASCII ADDTO :FNAME;
    SELECT '=============================================',
    :SPECIAL_CHARACTER FROM DUMMY ASCII ADDTO :FNAME;
    LABEL 100;
    FETCH CUR INTO :POS, :PROG, :NAME;
    GOTO 400 WHERE :RETVAL <= 0;
    SELECT STRCAT ('Stage ', ITOA (:POS), ' - ', :NAME),
    :SPECIAL_CHARACTER FROM DUMMY ASCII ADDTO :FNAME;
    /* The following record style code is because I couldn't get the
    lines in the correct order and format. This code works but it's not
    elegant */
    SELECT MAX (TEXTORD) INTO :MAX
    FROM PROGRAMSTEXT
    WHERE PROG = :PROG;
    :I = 0;
    LABEL 200;
    :I = :I + 1;
    SELECT TEXT, :SPECIAL_CHARACTER
    FROM PROGRAMSTEXT
    WHERE PROG = :PROG
    AND TEXTORD = :I
    ASCII ADDTO :FNAME;
    LOOP 200 WHERE :I < :MAX;
    SELECT '=============================================',
    :SPECIAL_CHARACTER FROM DUMMY ASCII ADDTO :FNAME;
    LOOP 100
    ;
    LABEL 400;
    CLOSE CUR;
    EXECUTE FILTER :SC, :SC, '13', :FNAME, :$.NAM;
    EXECUTE DELWINDOW 'f', :FNAME;
    LABEL 500;

    אלמוני
    אורח
    בס"ד

    ממש תודה רבה !
    עזר לי מאוד הכנסתי יזום לכול סוף שורה את הערך '^'
    ואח"כ השתמשתי ב
    EXECUTE FILTER :SC, :SC, '13', :FNAME, :$.NAM;

    על מנת להחליף ב ערך ה ascii של EOL ,

    ממש תודה רבה .

מוצגות 15 תגובות – 1 עד 15 (מתוך 16 סה״כ)
  • יש להתחבר למערכת על מנת להגיב.