none
הרצת SP מתוך SP כאשר יש מספר schemas ב-DB RRS feed

  • שאלה

  • יש לי DB עם מספר סכמות.

    בעקרון, כאשר מריצים SP מסכמה מסויימת, היא רצה בתור הסכמה הזאת, ולכן אם עושים SELECT לטבלה או EXEC לאובייקט מסוים הוא אמור לרוץ מהסכמה של ה-SP.

    לדוג:

    create procedure [aaa].[TestProcedure]

    ......

    exec procedureB

    .....

    procedureB אמור לרוץ כ-aaa.procedureB.

    הבעיה: משום מה, באחת הפרוצדורות, שדומה לדוגמא, הוא נותן שגיאה של: Could not find stored procedure. כמובן שהפרוצדורה קיימת, באותה סכמה כמו של הפרוצדורה שקוראת לה.

    יש למישהו רעיון מה יכול להיות שקרה פה???

    תודה.


    itaigitt, http://copypastenet.blogspot.com
    יום חמישי 10 מרץ 2011 15:31

תשובות

  • הי,

    זה בדיוק מה שרשמתי לך מה-Post הראשון !!! ציתות

    לגופו של עיניין, במידה וה- User שמריץ את הפרוצדורה הוא Owner על הסכימה אזי לא צריך לרשום את שם הסכימה אע"פ שיש כאן סיכון מכוון שבמידה וה- User הוא תחת sysadmin אז הוא יחפש את הפרוצדורה ב- dbo.

    לא מספיק להוריד אותו כ- db_owner ב- DB צריך גם להוריד אותו כ- sysadmin ב- Server Role עבור ה- Login.

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

     

     


    אסף שלם
    • סומן כתשובה על-ידי itaigitt יום רביעי 16 מרץ 2011 07:10
    יום ראשון 13 מרץ 2011 14:21
  • אז מה שיוצא מכל הדיון הארוך הזה שבמקרה ואני רץ מ-dbo (שהוא owner) אני חייב בכל פרוצדורה לציין את הסכימה, גם אם אני מריץ פרוצדורה\טריגר\.... שהם aaa? (כלומר לא רמה ראשונה, אלא אובייקטים פנימיים, שנקראים מתוך האובייקט לו אני אקרא עם הסכימה)?

    אין איזשהו מעקף?

     

    ועדיין אני לא מבין איך בשרת השני זה כן עובד......


    itaigitt, http://copypastenet.blogspot.com
    • סומן כתשובה על-ידי itaigitt יום רביעי 16 מרץ 2011 07:11
    יום ראשון 13 מרץ 2011 14:33

כל התגובות

  • לי לא ידוע על כך: אם לא מצויינת הסכימה במפורש- המערכת תחפש את האובייקט ב-dbo,

    וזה מה שקורה כאן.

    בדקתי והגעתי לאותה שגיאה:

    Create Schema Try;

     

    Create Proc Try.Try1 As

    Select GetDate() [GetDate];

     

    Create Proc Try.Try2 As

    Exec Try1;

    מה שמפתיע- המערכת לא התריעה כשייצרה את Try2 למרות שלכאורה לא מצאה את Try1.

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

    Create Proc Try.Try3 As

    Exec Try0;


    Geri Reshef http://gerireshef.wordpress.com
    יום חמישי 10 מרץ 2011 16:20
  • הי,

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

    לגופו של עיניין, במידה וה- User שמריץ את הפרוצדורה הוא Owner על הסכימה אזי לא צריך לרשום את שם הסכימה אע"פ שיש כאן סיכון מכוון שבמידה וה- User הוא תחת sysadmin אז הוא יחפש את הפרוצדורה ב- dbo.

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

    בכל מקרה אני ממליץ לרשום שם סכימה + אובייקט.

    בהצלחה


    אסף שלם
    יום חמישי 10 מרץ 2011 16:36
  • לפי מה שבדקתי, סכימת ברירת המחדל היא הסכימה של הקורא לאובייקט, ומה שתארתי עובד על DB זהה בשרת שונה.

    לכן אני חושב שמדובר הגדרות, כנראה בסגנון של מה שאסף רשם.

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

    תודה ושבוע טוב!


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 07:26
  • אני אכוון עוד קצת: השרת בו עובד העסק הוא SQL SERVER 2005, והבעייתי הוא 2008R2.

    נכון לרגע זה עוד לא מצאתי הבדלים בהגדרות....


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 07:53
  • הי איתי,

    תבדוק את השייכות של ה- Users ל- roles.

    במידה וה- User שנכשל בהרצה שייך - sysadmin אזי הוא יחפש את האובייקט בסכימת dbo גם אם ל- user הספציפי יש Schema Owner על סכימה אחרת.

     

    יום טוב, 


    אסף שלם
    יום ראשון 13 מרץ 2011 08:05
  • אסף - נראה שזאת לא הבעיה
    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 08:17
  • הי איתי,

    אם זו לא הבעיה כנראה שאתה נופל ב- pre compilation, תריץ את השאילתא ותראה האם אתה רואה את ההרצה ב-Trace.

    בו ננסה משהו נוסף:נתחיל ב- Login - תוודא שה- default_Schema של ה- Login שנכשל מוגדר בשם של הסכימה שבו מצויה הפרוצדורה ולא dbo.

    איך לבדוק -

    1. בתיקיית Security תחת ה- Instance תבחר Logins.

    2. קליק ימין על ה- Login name ו- מאפיינים.

    3. תחת User Mapping תוודא שה- default Schema ב- DB הרלוונטי לא משוייך ל- dbo.

    חלק שני,

    ברמת ה- DB הספציפי מתחת לתיקיית Security תבחר ב- User הרלוונטי, קליק ימני מאפיינים ותוודא שה- default schema לא מוגדרת כ- dbo.

    בהצלחה

     

     

     

     


    אסף שלם
    יום ראשון 13 מרץ 2011 09:21
  • היי אסף.

    קודם כל תודה.

    בדקתי לגבי ה- default_Schema, וזה מוגדר בסדר. 

    לגבי ה-pre compilation לא ממש הבנתי.

    אני אחדד את ההסבר לגבי המקרה שלי:

    יש לי כמה סכימות ב-DB, העיקריות הן dbo ואחת נוספת, נגיד aaa.

    כמו שתארתי בשאלה, יש לי פרוצדורה [aaa].[TestProcedure] שקוראת לפרוצדורה נוספת מאותה הסכימה - [aaa].[procedureB]. הקריאה נעשית ללא ציון הסכימה - exec procedureB.

    procedureB אמורה לרוץ כ-aaa.procedureB.

    כאשר אני מתחבר עם USER שנקרא כמו הסכימה אליו הוא משוייך - aaa, ההרצה של פרוצדורה TestProcedure מצליחה. כאשר אני מתחבר עם sa ששייך ל-dbo, הרצת הפרוצדורה TestProcedure נכשלת.

    בשרת השני (2005) - 2 ההרצות מצליחות.

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

    מכיוון שזה רץ ב-2005, אני מניח בסבירות גבוהה שזה עניין של הגדרות שונות. רק מה - אני עוד לא מוצה אותן......


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 09:41
  • הי איתי,

    הבעיה שלך ברורה וגם מה שברור זה שה- User השני היינו "sa" בדוגמא שמופיע למעלה מחפש את האובייקט בסכימה אחרת.

    הסיבות לכך הם לא רבות ושווה לנסות את כולן עד שמגיעים לפתרון.

    1. על תריץ עם sa הוא יחפש ב-dbo, בוא נניח ככה.

    2. תייצר לוגין חדש שיקרא aaa תמפה אותו רק ל- DB הרלוונטי כ- db_owner עם default schema - aaa.

    3. ברמת ה- DB תגדיר את user- aaa כ- owner על סכימת aaa.

    תנסה להריץ, עם יש שגיאה תריץ את השאילתה המופיע למטה ע"מ לוודא שהפרוצדורה נקראה ע"י User - aaa.

    Select user_name() 


    אסף שלם
    יום ראשון 13 מרץ 2011 10:03
  • כאשר אני מריץ עם aaa אין שגיאה. כאשר אני מריץ עם dbo יש שגיאה.

    העניין הוא שיהיו מצבים שאני אריץ עם dbo. לכן, ל-SP הראשונה, אני קורא exec aaa.TestProcedure , אבל בתוכה, בקריאה ל-procedureB אני לא קורא עם שם הסכימה.

    ושוב - בשרת אחר זה עובד כמו שאני מצפה שזה יעבוד.

    ואגב - procedureB קיים רק בסכימה aaa. לכן, בסתם הרצה, ולא משנה מי ה-user, זה אמור להגיע אליה. כל עניין הקדימויות - זה רק במקרה שיש aaa.procedureB ו- dbo.procedureB, ואז כל סכימה הולכת לאובייקט שלה.


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 11:06
  • הי איתי,

    dbo לרוב יחפש את הפרוצדורות בסכימת dbo, אני לא מכיר סנריו שבו אחרי חיפוש בסכימת dbo יש מעבר לסכימה אחרת לחיפוש נוסף.

    במקרה ההפוך, היינו חיפוש ב- aaa ואז מעבר ל- dbo, זה הגיוני.

    בכל מקרה במידה ואתה מריץ user-ים שונים למה לא לרשום "שם מלא"? למה ההתעקשות לרשום רק את שם האובייקט?

    יום טוב,


    אסף שלם
    יום ראשון 13 מרץ 2011 11:48
  • dbo לרוב יחפש את הפרוצדורות בסכימת dbo,  לכן אני מריף את ה-SP החיצונית עם קריאה מפורשת - exec aaa.TestProcedure.

    אבל בתוך ה-SP אני כבר aaa, לכן אני לא אמור לציין במפורש את הסכימה.

    מה עוד, שאין dbo.procedureB - ככה שבכל מקרה אמורים להגיע לaaa.procedureB.

    אני לא רושם שם מלא כי אני עושה פה חיבור של כמה DB-ים, וכרגע זה מצב נתון.


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 11:55
  • הי,

    מה שאתה יכול לעשות זה עבור Login - sa לשנות את ה- default schema ב- DB להיות aaa.

    ההתנהגות של הסכימה בתוך הפרוצדורה לא נכונה עבור user-ים שהם תחת sysadmin role, כמו sa לדוגמא.

    זה שהפרוצדורה נמצאת רק בסכימת aaa לא רלוונטי ל- sa מכוון שהוא יחפש ב- dbo ובמידה ולא ימצא תיזרק שגיאה.

    שים לב שה- error שאתה מקבל הוא לא מהקריאה לפרוצדורה אלא בשלב המקדים pre compilation, איך אתה יכול לדעת?

    1.תריץ Profiler ותנתר את הקריאה לפרוצדורה

    2.  ב- new query תריץ את הקריאה לפרוצדורה ותקבל את השגיאה.

    3. ב- profiler תראה האם הקריאה מופיע, לדעתי לא מכוון שהנפילה היא בשלב של הכנת הפרוצדורה להרצה ולא בשלב ההרצה.

    בהצלחה, 


    אסף שלם
    יום ראשון 13 מרץ 2011 12:31
  • אבל מה יכול להיות ההבדל מול השרת בו אותה סיטואציה עוברת ללא שגיאות?
    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 12:33
  • אגב, אני לא רואה את השגיאה בפרופיילר.....
    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 12:40
  • הי,

    ההגדרות עבור ה- Login -sa עבור כל אחד מבסיסי הנתונים זהים?

    הגדרות עבור user -dbo בבסיס נתונים הספציפי זהות?

    חשוב לבדוק את ה- server Role ו- Database roles עבור ה- user-ים שמשתתפים בתהליך מכוון שהשתייכות לקבוצות יכולה לשנות את ה- ownership.

     


    אסף שלם
    יום ראשון 13 מרץ 2011 12:47
  • לפי מה שאני בדקתי אין הבדלים.... האמת אני הולך ומתבלבל....
    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 12:54
  • את הקריאה לפרוצדורה אתה רואה?


    אסף שלם
    יום ראשון 13 מרץ 2011 12:56
  • כן. גם starting וגם completed.

    אם לא הייתי רואה את הביצוע - הייתי חושב שזה הצליח...


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 12:57
  • הי,

    משהו לא ברור לי, אתה רואה sp:completed אז איפה אתה מקבל את השגיאה? אתה בטוח שאתה מריץ עם ה- user  הנכון.

     


    אסף שלם
    יום ראשון 13 מרץ 2011 13:07
  • אני רואה שגיאה שאני מריץ מה-management studio.

    ואגב - גם שם - אני מקבל חזרה תוצאת select שמתבצעת לאחר הקריאה ל-procedureB, פשוט גם עם הודעות השגיאה.

    אולי בעצם הפרוצדורה רצה כמו שצריך עם משהו בסגנון warning? (יש בכלל אופציה כזאת?)

    ואם כן, ואכן חוזרת לי תוצאה - אפשר לנטרל החזרת השגיאות האלו (בעיקר לאפליקצייה) ולהחזיר רק את התשובה?


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 13:12
  • הי,

    Managment studio מריץ את השאילתות עם ה- user שממופה ל-Login שאיתו נכנסתה.

    תריץ את הפרוצדורה כמו בקטע קוד המצורף ותראה אם אתה מקבל שגיאה.

    לגבי ה-warnings אתה לא יכול לנתרל אבל אתה יכול לתפוס את השגיאה באפליקציה ולהתעלם ממנה.

    execute as user = 'testuser'
    Go
    exec test.test4 
    

    אסף שלם
    יום ראשון 13 מרץ 2011 13:38
  • בדקתי ע"י Select user_name(), פעם עם aaa ופעם עם dbo.

    aaaעבר ללא הודעות שגיאה, dbo החזיר תוצאות אבל עם שגיאות.


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 13:47
  • אגב, ראיתי ב-MSDN ש-

    The value of DEFAULT_SCHEMA is ignored if the user is a member of the sysadmin fixed server role. All members of the sysadmin fixed server role have a default schema of dbo.

    אם אני אוריד את dbo מלהיות db_owner ב-DB שלי זה יכול לגרום איזשהו נזק?


    itaigitt, http://copypastenet.blogspot.com
    יום ראשון 13 מרץ 2011 14:02
  • הי,

    זה בדיוק מה שרשמתי לך מה-Post הראשון !!! ציתות

    לגופו של עיניין, במידה וה- User שמריץ את הפרוצדורה הוא Owner על הסכימה אזי לא צריך לרשום את שם הסכימה אע"פ שיש כאן סיכון מכוון שבמידה וה- User הוא תחת sysadmin אז הוא יחפש את הפרוצדורה ב- dbo.

    לא מספיק להוריד אותו כ- db_owner ב- DB צריך גם להוריד אותו כ- sysadmin ב- Server Role עבור ה- Login.

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

     

     


    אסף שלם
    • סומן כתשובה על-ידי itaigitt יום רביעי 16 מרץ 2011 07:10
    יום ראשון 13 מרץ 2011 14:21
  • אז מה שיוצא מכל הדיון הארוך הזה שבמקרה ואני רץ מ-dbo (שהוא owner) אני חייב בכל פרוצדורה לציין את הסכימה, גם אם אני מריץ פרוצדורה\טריגר\.... שהם aaa? (כלומר לא רמה ראשונה, אלא אובייקטים פנימיים, שנקראים מתוך האובייקט לו אני אקרא עם הסכימה)?

    אין איזשהו מעקף?

     

    ועדיין אני לא מבין איך בשרת השני זה כן עובד......


    itaigitt, http://copypastenet.blogspot.com
    • סומן כתשובה על-ידי itaigitt יום רביעי 16 מרץ 2011 07:11
    יום ראשון 13 מרץ 2011 14:33
  • הי איתי

    חיובי, מגירסאות sql server 2005 רצוי, שאני אומר רצוי אני מתכוון חייב - אלא אם כן מתחשק לך לקבל טלפון בזמן הכי קריטי שמשהו לא עובד, להשתמש בשם מלא schema_name.object_name.

    בכל דרך אחרת אתה מסתכן בבעיית הרשאות.

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

    אתה יכול להתקשר אלי היום בערב בין 18:00 ל- 18:30 אני יהיה בדרך הביתה אפשר לדסקס את זה ןאח"כ לעדכן בפורום.

    0542208649.

    אחה"צ נעימים,


    אסף שלם
    יום ראשון 13 מרץ 2011 14:49