top of page

זהירות, SP_RENAME!

אורי קליל החורש

מומחה SQL Server בעל כ-15 שנות ניסיון מגוון בתחום.

DBA בחברה מתמחה בפיתוח טכנולוגיות חדשניות לקידום תעשיית הרפואה מטעם נאיה טכנולוגיות.

כל DBA מתחיל מכיר את פקודת T-SQL בשם sp_rename שמטרתה לשנות שם של אובייקט. לא על זה באתי לכתוב, אלא על בעיה נסתרת שנגרמת מפקודה זו.

ההמשך עלול להישמע כמו באג, אבל האמת שמיקרוסופט מזהירה מזה ב MSDN, רק שקשה מאד להבין משם מה הבעיה. מתוך ה MSDN :

Renaming a stored procedure, function, view, or trigger will not change the name of the corresponding object name in the definitioncolumn of the sys.sql_modules catalog view. Therefore, we recommend that sp_rename not be used to rename these object types. Instead, drop and re-create the object with its new name.

אז מה הבעיה?

לפני תאור הבעיה אציין שבחברה בה אני נמצא כל פעם לאחר התקנת גרסה התקבלה תלונה שבמקרים מסוימים, ללא חוקיות נראית לעין, קוד ישן שמזמן כבר שונה ועודכן פתאום "חזר לחיים"!! זה קרה בעיקר בפרוצדורות וב views. בכל פעם שהבעיה קרתה לאחר מספר נסיונות לפתור אותה הבאנו קוד מתוקן מה source control והכל נרגע. עד לפעם הבאה...

הסתבר שהבעיה קשורה לנושא שלנו. כדי לסמלץ את הבעיה נריץ את הקוד הבא:

use tempdb

GO

if object_id('TestView') is not null

drop view TestView_1

GO

if object_id('TestView_2') is not null

drop view TestView_2

GO

create view TestView_1

as

select 'No one can move me!' as view_desc

GO

exec sp_rename 'TestView_1', 'TestView_2'

GO

create view TestView_1

as

select 'I did it !! I replaced the previous view!' as view_desc

GO

כעת אם נבדוק את תוכן ה Views:

select 'TestView_1' as View_Name, view_desc from TestView_1

UNION ALL

select 'TestView_2' as View_Name, view_desc from TestView_2

נקבל:

כעת יש שני views שונים במערכת, עם שמות שונים,תוכן שונה וקוד שונה. אולם אם נציץ בטבלת סיסטם sys.sql_modules, נראה את מה שהוזהרנו ב MSDN:

select object_name(object_id) as Object_name, definition

from sys.sql_modules

where object_name(object_id) like 'TestView%'

בשני המקרים הטקסט מתחיל ב Create View TestView_1! נראה רע, אבל זה עדיין לא הבעיה.

מסתבר שבסוף כל שדרוג, היה שלב בו קומפלו כל האובייקטים ב database, או במילים אחרות בוצע sp_refreshview לכל ה views במערכת.

כעת ננסה בדוגמה שלנו –

exec sp_refreshview TestView_2

ונבדוק שוב את תכולת ה views נקבל הפעם:

ז"א הקוד של testView_1 נדרס ע"י הקוד הישן שלו!

כאן יש בשורה קטנה, בין אם זה באג או לא, הבעיה שהוזכרה כאן ככל הנראה תוקנה בגרסאות SQL 2012 ומעלה, אם כי בטבלת sys.sql_modules עדיין קיים שם האובייקט הישן כמו שצוין מקודם.

אז מה אפשר לעשות? להיזהר מ sp_rename! איפה שאפשר לעשות drop/create ולא rename.

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

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

Comments


Featured Posts
Check back soon
Once posts are published, you’ll see them here.
Recent Posts
Archive
Search By Tags
No tags yet.
Follow Us
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square
bottom of page