הבלוג של גרי רשף

15/03/2011

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

Filed under: Uncategorized — תגיות: , , , — גרי רשף @ 21:14

במקומות עבודה מסודרים (לא כאלה שמפתחים על ה-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 ..

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

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

מודעות פרסומת

2 תגובות »

  1. בפרוצדורות וכו' כדאי לעשות drop…create בכל מקרה כדי שיעודכנו סטטיסטיקות, cache וכדו'.
    במקרה של הוספת שדה לטבלה ניתן ורצוי לבדוק ספציפית אם השדה קיים, ורק אז להריץ את ה-ALTER. ככה ניתן להריץ את הסקריפט כמה פעמים שצריך. בדיקה ע"י: if not exists (select id from syscolumns where id=object_id('TABLE_NAME') and name='COLUMN_NAME')

    תגובה של איתי — 16/03/2011 @ 09:26

    • איתי: לגבי ההערה הראשונה- תודה רבה! לא הייתי ער לכך, אז בטח ובטח שעדיף לבצע Drop & Create, ולא לשכוח לתת מחדש הרשאות.

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

      תגובה של גרי רשף — 16/03/2011 @ 11:39


RSS feed for comments on this post. TrackBack URI

להשאיר תגובה

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

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

בלוג בוורדפרס.קום.

%d בלוגרים אהבו את זה: