none
ביצוע סקריפט בעזרת sp_executesql או בכל דרך אחרת. RRS feed

  • שאלה

  • שלום לכולם,

    יש לי שרת dev שכל ה-DBs בו נמצאים ב-Full Recovery Mode ללא סיבה מוצדקת. אני רוצה להפוך את כולם ל-Simple. מצאתי סקריפט (נקרא לו s1)

    http://sqlserverpedia.com/blog/sql-server-bloggers/setting-all-databases-to-simple-recovery-mode, שבונה סקריפט אחר (נקרא לו s2), שמבצע בדיוק את מה שאני צריך. אני מנסה לבצע את s1 בעזרת  sp_executesql בצורה הבאה:

    DECLARE @SQLString nvarchar(500);
    SET @SQLString =
         N'select 'ALTER DATABASE [' + name + '] SET RECOVERY SIMPLE'
    				from sys.databases
    				where database_id > 6
    				and recovery_model_desc = 'FULL''
    
    EXEC sp_executesql @SQLString

    והתהליך נכשל הגלל הגרשיים. אז השאלה נכונה היא, כנראה, איך אני משרשר גרש בשאילתא?



    • נערך על-ידי Ivan Radchenko יום שלישי 17 יולי 2012 12:00
    יום שלישי 17 יולי 2012 09:54

תשובות

  • אני לא יודע מה אתה מנסה להשיג בשאילטה אבל

    א. הלינק שבור

    ב. יש לך כאן בעיה עם השירשור אני משער שזה רק חלק להשאילטה המקורית.

    ראה את הלינק הזה תריץ את כל השורות וזה אמור לתת לך פתרון

    http://bradkingsley.com/set-all-databases-to-simple/

    מצ"ב עוד לינק שעושה את אותו דבר רק עם שרשור כמו שצריך ותוכל ללמוד ממנו

    http://www.cnblogs.com/ahjxxy/archive/2012/01/17/2324631.html

    יום שלישי 17 יולי 2012 10:03
  • היי איוון (שוב),

    אני מצטער, אבל אתמול לא הייתי ליד SSMS כאשר עניתי לך, ולכן לא ירדתי לסוף דעתך. הרעיון שלך לפי דעתי הוא גאוני.  אבל יש בעיה אחת איתו, אתה בעצם מריץ EXEC ל- String הוא שאילתה, כאשר מה שאתה צריך, זה להריץ EXEC לתוצאה שחוזרת לך מהשאילתה!! מצורף קוד לדוגמא, איך לבצע זאת. אצלי זה עבד. בצורה הזו באמת לא צריך להשתמש ב- Corsur ובפקודה אחת, תשנה את כל ה- Recovery Model של בסיסי הנתונים שלך. 

    בהצלחה,

    יוסי 

    DECLARE @SQLString NVARCHAR(MAX) = ''
    SELECT 
    	@SQLString += 'ALTER DATABASE '   + name +   ' SET RECOVERY SIMPLE; ' + CHAR(13)
    FROM 
    	sys.databases
    				
    WHERE 
    	database_id > 6
    AND 
    	recovery_model_desc = 'FULL'  
    
    --PRINT @SQLString  -- Check the string before executing
    
    EXEC sp_executesql @SQLString 


    • נערך על-ידי Yossi Hakikat יום רביעי 18 יולי 2012 07:11
    • סומן כתשובה על-ידי Ivan Radchenko יום ראשון 22 יולי 2012 13:39
    יום רביעי 18 יולי 2012 07:11

כל התגובות

  • אני לא יודע מה אתה מנסה להשיג בשאילטה אבל

    א. הלינק שבור

    ב. יש לך כאן בעיה עם השירשור אני משער שזה רק חלק להשאילטה המקורית.

    ראה את הלינק הזה תריץ את כל השורות וזה אמור לתת לך פתרון

    http://bradkingsley.com/set-all-databases-to-simple/

    מצ"ב עוד לינק שעושה את אותו דבר רק עם שרשור כמו שצריך ותוכל ללמוד ממנו

    http://www.cnblogs.com/ahjxxy/archive/2012/01/17/2324631.html

    יום שלישי 17 יולי 2012 10:03
  • תודה רבה על הקישורים, זה בדיוק מה שאני צריך! בכל זאת, הייתי רוצה לפתור את בעיה עם הדרך שלי, כי היא דרך הכי יפה ופשותה בעיני.

    א. הלינק עובד, רק צריך להוריד את ה-] בסוף, מצטער.

    ב. בהחלט יש לי בעית שירשור, זאת בדיוק השאלה שלי, מה הבעיה? כאשר אני נותן ל-@sqlstring ערך פשוט, אין בעיה. לדוגמא:

     
    SET @SQLString ='select 1'

    אבל כאשר אני מנשה לדחוף לו את שאילתא הבאה, הסקריפט נופל בגלל השירשור:

    select 'ALTER DATABASE [' + name + '] SET RECOVERY SIMPLE' from sys.databases where database_id > 4 and recovery_model_desc = 'FULL'

    יום שלישי 17 יולי 2012 11:37
  • היי איוון,

     אם הבנתי אותך נכון, אתה רוצה ליישם סקריפט שמשנה את ה- Recovery Model של בסיסי הנתונים בסביבת ה-Dev שלך.  הבעיה עם הסקריפט שלך היא שאתה מריץ גם פקודת SELECT וגם פקודת ALTER באותו ה- Statement בו זמנית, וזה כמובן לא אפשרי. 

    על מנת לבנות סקריפט שכזה. אתה צריך להשתמש ב- Cursor וגם בשאילתה דינמית . Tetitu צירף בתשובתו קישורים לא רעים, אם הם לא עוזרים לך, תנסה לקרוא על כל אחד הנושאים (Cursor ושאילתות דינמיות). 

    מקווה שעזרתי,

    יוסי חקיקת


    • נערך על-ידי Yossi Hakikat יום שלישי 17 יולי 2012 11:47
    יום שלישי 17 יולי 2012 11:47
  • בעצם יש לך 2 שלבים.

    שלב ראשון מציאת כל בסיסי הנתונים ובניית השאילטה לשינוי הרקוברי שלו.

    שלב שני הרצה של התוצאה של השלב הראשון

    תוצאת השאלטה שלך

    select 'ALTER DATABASE [' + name + '] SET RECOVERY SIMPLE' from sys.databases where database_id > 4 and recovery_model_desc = 'FULL'

    היא טקסט :

    ALTER DATABASE [MYFIRST_TABLE] SET RECOVERY SIMPLE

    ALTER DATABASE [MYSECOND_TABLE] SET RECOVERY SIMPLE

    ALTER DATABASE [MYTHIRD_TABLE] SET RECOVERY SIMPLE

    ואת התוצאה הזאת אתה צריך להריץ שוב.

    עכשיו מכיוון שכל שורה היא רשומה משל עצמה אתה צריך לעשות לולאה על השאילטה הראשונה ולשרשר את הטקסט שחוזר לך(או כבר להריץ את התוצאה בתוך הלולאה).

    ורק לאחר שיש לך את הרשימה עם כל השאילטות לעדכון אתה יכול להריץ אותם.

    ולגבי השאלה שלך של השרשור

    select 'this a text and now i add one comma '' look here is a comma'

    בקיצור או אתה צריך גרש בתוך התוצאה של הטקסט ושהטקט לא יחתך שים פעמים גרש

    יום שלישי 17 יולי 2012 13:19
  • היי איוון,

     אם הבנתי אותך נכון, אתה רוצה ליישם סקריפט שמשנה את ה- Recovery Model של בסיסי הנתונים בסביבת ה-Dev שלך.  הבעיה עם הסקריפט שלך היא שאתה מריץ גם פקודת SELECT וגם פקודת ALTER באותו ה- Statement בו זמנית, וזה כמובן לא אפשרי. 

    היי יוסי. הבנתה אותי נכון, זה בדיוק מה שאני רוצה לעשות, אבל אני לא מריץ את ה-select ו-alter באותו statement. בסוף הצלחתי לפתור את בעית השירשור:

    DECLARE @SQLString nvarchar(2000);
    SET @SQLString ='select '+''''+'ALTER DATABASE ['+''''+ ' + name + '+''''+'] SET RECOVERY SIMPLE'+''''+
    				' from sys.databases where database_id>4 and recovery_model_desc ='+''''+'FULL'+''''
    exec (@sqlstring)

    אבל הסקריפט הזה מחזיר לי טבלה ולא מחרוזת, כלומר הפלט הוא  משהו כזה:

    ALTER DATABASE [a] SET RECOVERY SIMPLE
    ALTER DATABASE [b] SET RECOVERY SIMPLE
    ALTER DATABASE [c] SET RECOVERY SIMPLE
    ALTER DATABASE [d] SET RECOVERY SIMPLE

    לכן עכשיו אני מסכים איתך, אני חייב להעזר ב-cursors וכדאי לי להשתמש בלינקים של tetitu. תודה!

    יום שלישי 17 יולי 2012 13:19
  • בעצם יש לך 2 שלבים.

    שלב ראשון מציאת כל בסיסי הנתונים ובניית השאילטה לשינוי הרקוברי שלו.

    שלב שני הרצה של התוצאה של השלב הראשון

    בדיוק כך, כבר הבנתי את זה לבד. תודה רבה יל העזרה!
    יום שלישי 17 יולי 2012 13:27
  • היי איוון (שוב),

    אני מצטער, אבל אתמול לא הייתי ליד SSMS כאשר עניתי לך, ולכן לא ירדתי לסוף דעתך. הרעיון שלך לפי דעתי הוא גאוני.  אבל יש בעיה אחת איתו, אתה בעצם מריץ EXEC ל- String הוא שאילתה, כאשר מה שאתה צריך, זה להריץ EXEC לתוצאה שחוזרת לך מהשאילתה!! מצורף קוד לדוגמא, איך לבצע זאת. אצלי זה עבד. בצורה הזו באמת לא צריך להשתמש ב- Corsur ובפקודה אחת, תשנה את כל ה- Recovery Model של בסיסי הנתונים שלך. 

    בהצלחה,

    יוסי 

    DECLARE @SQLString NVARCHAR(MAX) = ''
    SELECT 
    	@SQLString += 'ALTER DATABASE '   + name +   ' SET RECOVERY SIMPLE; ' + CHAR(13)
    FROM 
    	sys.databases
    				
    WHERE 
    	database_id > 6
    AND 
    	recovery_model_desc = 'FULL'  
    
    --PRINT @SQLString  -- Check the string before executing
    
    EXEC sp_executesql @SQLString 


    • נערך על-ידי Yossi Hakikat יום רביעי 18 יולי 2012 07:11
    • סומן כתשובה על-ידי Ivan Radchenko יום ראשון 22 יולי 2012 13:39
    יום רביעי 18 יולי 2012 07:11
  • היי יוסי.

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

    1) בשורה שלישית יש לך "=+", האם יש לזה משמעות? הסקריפט עובד גם בלי זה.

    2) כנ"ל עבור "(13) CHAR +" באותה שורה.

    3) PRINT @SQLSTRING משום מה לא מחזיר שום הודעה בכלל. למה זה יכול להיות? כמובן שהורדתי את ה"--".

    יום ראשון 22 יולי 2012 14:05
  • היי איוון,

    קודם כל, שמחתי לעזור! לגביי שאלותייך: 

    1 + 2) לסימן += וכמו כן גם ל- Char אין משמעות אמיתית, זוהי רק דרך לשרשר את המידע שורה מתחת לשורה על מנת שתוכל לקרוא את המידע בצורה ברורה יותר (במקום שורה אחת ארוכה שמכילה הרבה פקודות, אתה מקבל בכל שורה פקודה אחת, לטעמי זה יותר נוח).

    3) מוזר שלא עובד לך ה- Print משום שאצלי זה עובד...... יש לי הרגשה שזה קשור לפילטרים ב-  WHERE. אולי הרצת כבר הרצת את הפקודה בעזרת  SP_EXECUTESQL, ואז באמת לא תקבל שום תוצאה משום שכבר אין לך שום מסד נתונים עם Recovery Model שהוא FULL. 

    יוסי

    יום ראשון 22 יולי 2012 14:20
  • היי יוסי,

    1+2) עדיין לא הבנתי. אתה מתכוון לשרשר את מידע בקוד או בפלט של ה-PRINT? כאשר אתה מוסיף למשתנה את Char(13), אתה למעשה מוסיף 13 רווחים? לגבי "=+" אין לי רעיונות בכלל... :)

    3) כמובן, זוהי בדיוק הסיבה. הפכתי את אחד ה- DBs ל- FULL וקיבלתי את הפלט. איך לא חשבתי על זה?

    תודה!

    יום שני 23 יולי 2012 04:42
  • היי איוון,

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

    הסימן += משמעו, שירשור של המשתנה לעצמו כלומר המשתנה שווה לעצמו + הערך שאתה מוסיף לו. למעשה זוהי רק דרך כתיבה מקוצרת. באותה מידה יכולת לרשום :

    DECLARE @SQLString NVARCHAR(MAX) = ''
    SELECT 
    	@SQLString = @SQLString +  'ALTER DATABASE '   + name +   ' SET RECOVERY SIMPLE; ' + CHAR(13)
    FROM 
    	sys.databases
    				
    WHERE 
    	database_id > 6
    AND 
    	recovery_model_desc = 'FULL'  

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

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

    מקווה מאד שהפעם עשיתי עבודה טובה ביותר בלהסביר......

    יוסי חקיקת


    • נערך על-ידי Yossi Hakikat יום רביעי 25 יולי 2012 12:30
    יום שני 23 יולי 2012 13:01
  • היי יוסי,

    הכל ברור לי עכשיו, תודה! לא ראיתי את זה מקודם, כי רק DB אחד שבשרת שלי היה ב-FULL וכתוצאה מכך קיבלתי רק שורה אחת של פלט, בלי קשר ל- "=+" ו-Char (13)... :) 

    יום רביעי 25 יולי 2012 08:13