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

15/03/2011

אין תגובות

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

1. פקודות Create לאובייקטים חדשים שיש ליצור.

2. פקודות Alter לאובייקטים קיימים שיש לשנות.

3. הוספה ושינוי נתונים בטבלאות ניהול.

4. הרשאות (בדרך כלל בהמשך ל-Create הנ"ל).

5. שונות..

הסקריפט צריך להיות בנוי כך שהרצה כפולה שלו לא תגרום נזקים, למשל:

בהמשך לסעיף 1 – לא תנסה ליצור אובייקטים שכבר נוצרו,

ובהמשך לסעיף 3 – לא תנסה להוסיף נתונים שכבר קיימים.

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

כל עוד מדובר ביצירה של טריגרים, פרוצדורות, פונקציות או Views – ניתן להקדים ל-Create פקודת Drop מותנית:

If Object_ID('MyNewObject') Is Not Null Drop .. MyNewObject;

Go

אם מדובר ב-Alter לאובייקטים כנ"ל- לא תהיה כל בעייה אם הקוד יורץ מספר פעמים; וכך במתן הרשאות או בגריעתן.

כשמדובר בטבלה – הטיפול ב-Create אמור להיות הפוך; בודקים אם היא קיימת, ואם כן – לא יוצרים. טבלה עם נתונים לא מבטלים בקלות דעת:

If Object_ID('MyNewTable') Is Not Null

    Begin

    Create Table ..

    Grant Select On ..

    ..

    End;

כשמשנים טבלה- יש לבדוק אם השינוי בוצע:

עבור אובייקטים כמו Check Constraint ניתן להשתמש ב-Object_ID כנ"ל (בתנאי שהקפדנו לתת לו שם בעצמנו ולא סמכנו על השמות שהמערכת ממציאה).

עבור אובייקטים כמו Primary Key גם ניתן להשתמש ב-Object_ID אבל כדאי לשים לב שאם כבר יש לטבלה Primary Key בשם אחר – לא ניתן להוסיף עוד אחד, ונסיון לעשות זאת יחולל שגיאה. במקרה זה אפשר לבדוק כך:

If ObjectProperty(Object_ID('MyTbl'),'TableHasPrimaryKey')<>1

    Alter Table MyTbl ..

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

If Col_Length('MyTbl','MyCol') Is Null

    Alter Table MyTbl Add MyCol ..

לגבי הוספת נתונים לטבלאות ניהול – כתבתי על כך פוסט בעבר.

כמובן שניתן לבצע את כל הבדיקות הנ"ל בעזרת טבלאות המערכת, אבל למה לסבך את מה שיש לו פתרון ידידותי?

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *