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

15/03/2011

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

שייך לקטגוריה: 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 של התגובות על הרשומה הזו טרקבאק קישור

כתיבת תגובה

Fill in your details below or click an icon to log in:

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

ערכת עיצוב: Shocking Blue Green. בלוג בוורדפרס.קום.

Follow

Get every new post delivered to your Inbox.

הצטרפו אל 25 שכבר עוקבים אחריו