השימוש ב-Proxy וב-Credentials

29/04/2010

הפעלה של ג'ובים או של פרוצדורות מערכת שפועלות מול ה-File System (המחיצות והקבצים) הן בעייתיות מכיוון שמי שמבצע את הפקודות מזדהה בתור ה-Agent של ה-SQL Server ולא בתור המשתמש הספציפי שהריץ את הפקודה, וכך המשתמש מקבל הרשאות חריגות שעלולות להיות מנוצלות לרעה: הוא יכול להגיע למחיצות וקבצים שאין לו הרשאה להגיע אליהם או לשנותם, הוא יכול להריץ פקודות SQL בעזרת SQLCmd ולעשות ככל העולה על רוחו. הפתרון לבעייה הוא ליצור Proxy Account כך שהכלים הנ"ל יזדהו איתו ויקבלו את ההרשאות של ה-Credential המשוייך אליו, הרשאות שניתן להגביל אותן בהתאם לצורך. הפעלת ג'ובים הדוגמה להלן מניחה שהשרת...
אין תגובות

שימוש ב-Sparse Columns וב-Column_Set

28/04/2010

כאשר קולטים רשומות הכוללות Null – הם (ה-Nulls) תופסים מקום, בניגוד למה שאולי היינו מצפים. למשל בעמודות מסוג Varchar ששומרות רק את המחרוזת שקלטנו ללא מקומות פנויים לתווים המיותרים (אם נניח קלטנו מחרוזת באורך 10 תווים לשדה שיכול לקלוט עד 50 תווים) יש צורך לשמור בכל רשומה מידע לגבי אורך המחרוזת השמורה באותה עמודה. החל מגרסת SQL Server 2008 יש אפשרות להגדיר שדות כ-Sparse Columns ואז לא מבוזבז מקום כשיש Null, אלא רק כשאין ערך (כלומר- טוב להשתמש בהן כשברוב המקרים יש Null). פטנט זה מגיע יחד עם האופציה ליצור Column_Set שזו מעין עמודה מחושבת המציגה בתור Xml את כל שדות ה-Sparse: Create...
אין תגובות

האח הגדול עינו פקוחה (4) – שימוש ב-Extended Events

27/04/2010

נפתח ביצירת Event Session (יש לוודא שהמחיצה קיימת!):   CREATE EVENT SESSION MyEventSession ON SERVER ADD EVENT sqlserver.sql_statement_completed(ACTION (sqlserver.database_id, sqlserver.sql_text, sqlserver.session_id,sqlserver.tsql_stack, sqlserver.username, sqlserver.client_hostname) WHERE sqlserver.database_id=2), ADD EVENT sqlserver.sql_statement_starting(ACTION (sqlserver.database_id, sqlserver.sql_text, sqlserver.session_id,sqlserver.tsql_stack, sqlserver.username, sqlserver.client_hostname) WHERE sqlserver.database_id=2) ADD TARGET package0.asynchronous_file_target(set FileName = 'c:\tmp\EventSession.xel',MetaDataFile = 'c:\tmp\EventSession.xem') GO 1. נאסוף נתונים על אירועי sql_statement_starting ו-sql_statement_completed. כדי לקבל פרטים על אירועים אחרים שניתן לתחקר:   Select * ...
אין תגובות

תנאי Where המאפשר להציג את כל הרשומות

26/04/2010

הבעייה הזו אופיינית לדוחות: בנינו דוח המציג שליפה מסויימת, והוא כולל אפשרות לבחור פרמטר מסויים. למשל- המשתמש יכול לבחור ID כלשהו, והדוח יציג את הרשומה או הרשומות עם אותו ID; אבל אנחנו רוצים, בנוסף, לאפשר למשתמש להציג את כל הרשומות. פתרונות מסורבלים לא חסרים: ליצור שני דוחות שונים, או להריץ קוד שיבנה באופן דנאמי את ה-SQL – במקרה אחד עם פילטר ובאחר – בלעדיו; אבל יש גם פתרונות אלגנטיים במחיר שווה לכל נפש, שלאחר שרואים אותם אומרים במבט מופתע: "וואלה? איך לא חשבתי על זה.. הפתרון הפשוט...
אין תגובות

חיפוש עם תווים בעייתיים

25/04/2010

נניח שאנחנו רוצים לחפש שורות בהן מופיע הצירוף 100% בשדה טקסטואלי, למשל במקרה הזה: Create Table #Ovdim(ID Int Not Null Primary Key, Shem VarChar(50), Heara NVarChar(Max)); Go Insert Into #Ovdim Values(1,'Ada','העובדת הראשונה'); Insert Into #Ovdim Values(2,'Beni','הוא 100% בסדר'); Insert Into #Ovdim Values(3,'Galit','גם היא בסדר'); Insert Into #Ovdim Values(4,'Dan','יש לו 100 במתימטיקה'); Insert Into #Ovdim Values(5,'Hila',Null); לכאורה קלי קלות (כדי לקבל את בּנִי): Select * From #Ovdim Where...
אין תגובות

שאילתות על מבנה של טבלאות זמניות

21/04/2010

נשאלתי כיצד ניתן לשלוף פרטים על מבנה טבלה זמנית. הטבלאות הזמניות נשמרות ב-tempdb ושם גם הפרטים עליהן. ניצור טבלה זמנית בדטבייס אחר: Use AdventureWorks; Go Create Table #TmpTbl(MyInt Int, MyString Varchar(10)); Go ונשלוף פרטים לגבי המבנה שלה: Select * From tempdb.sys.columns Where object_id=OBJECT_ID('tempdb.dbo.#TmpTbl'); יש לשים לב שבשליפה מופיע פעמיים tempdb ללא קשר לדטבייס בו היינו עת הטבלה נוצרה. אם ניצור Session חדש (למשל- על ידי פתיחת New Query ב-Management Studio) ונריץ משם את השליפה...
אין תגובות

האח הגדול עינו פקוחה (3) – מי הציץ בטבלה שלי?

15/04/2010

לא יפה להסתכל בטבלאות של אחרים, ובעזרת מנגנון ה-Audit נוכל ללכוד את מי שהציץ ונפגע. ניצור מחיצה מתאימה בדיסק של השרת לשם יופנו נתוני המעקב, ונגדיר Audit (אובייקט ברמת השרת) למחיצה זו. את המחיצות ניתן ליצור ידנית אם ה-xp_CmdShell אינו מאופשר: Use Master Go xp_cmdshell 'md C:\MyAudit\' Go CREATE SERVER AUDIT My_Server_Audit TO FILE (FILEPATH='C:\MyAudit\', MAXSIZE = 5MB, MAX_ROLLOVER_FILES = 100, RESERVE_DISK_SPACE = ON); Go ALTER SERVER AUDIT My_Server_Audit with (STATE = ON); Go כעת נגדיר Database Audit Specification (אובייקט ברמת הדטבייס) שבעזרת הנ"ל יעקוב אחר מה שנחליט, כאשר לצורך העניין נעקוב אחר פעולות DML שכוללות Select, Update, Delete, Insert; ובמחשבה שניה – כדי להדגים שינוי בדיעבד בהגדרה...
אין תגובות

שימוש ב-Partitioned Tables

13/04/2010

Partitioned Tables הוא שמה של הטכנולוגיה המאפשרת לחלק טבלה לפי תחומים למספר חלקים, ובכך להקל על השימוש. דוגמה אופיינית יכולה להיות חלוקה של טבלת המכירות לפי שנים – כך שלכל שנה יהיה Partition משלה, או לפחות שלשנה השוטפת שמולה נעשית עיקר העבודה יהיה Partition משלה. חיפוש ושינוי נתונים צפוי להיות אז יעיל ומהיר יותר, ובנוסף ניתן בקלות לצרף טבלאות אחרות כ-Partition-ים חדשים, או להפוך Partition-ים קיימים לטבלאות חיצוניות, וכל זה מבלי "לשלם" במחיר של יבוא ויצוא...
אין תגובות

כמה פעמים מופיעה מחרוזת אחת בתוך אחרת?

09/04/2010

טריק עתיק יומין ופשוט ששלפתי מהבוידעם לאחר שנתקלתי בדוגמה הזו שמצליחה לסבך את הבעייה ללא צורך. הטריק הוא למצוא את ההפרש בין אורך המחרוזת המקורית, לבין אורך המחרוזת לאחר שהסרנו ממנה את תת המחרוזת. למשל- כמה פעמים מופיעה האות e בשם Geri Reshef? אורך השם Geri Reshef הוא 11 תווים, אם נוריד את e נקבל Gri Rshf שאורכו 8 תווים, ומכאן ש-e מופיע 3=11-8 פעמים. לו הייתי מחפש תת מחרוזת שאורכה גדול מ-1, היה עלי לחלק את התוצאה באורך תת המחרוזת. דוגמה לחיפוש מחרוזת באורך תו אחד: Declare @S1 Varchar(Max), @S2 Varchar(Max); Select @S1='Geri Reshef', ...
אין תגובות

איקס מיקס דריקס

08/04/2010

משחק מטופש למדי שמהר מאוד ממצה את עצמו לאחר שמבינים שהוא מוביל לתיקו (אלא אם כן מדובר בטירון), אך מה לעשות? לפעמים תכנות ו-DBA-ות הם גם עיסוקים מטופשים.. נתחיל ביצירת טבלה T_Mazavim שתכלול את כל המצבים החוקיים האפשריים של הלוח: 1. בהנחה ש-X מתחיל, ההפרש בין מספר ה-X-ים וה-O-ים הוא לכל היותר 1. 2. כשמישהו מנצח או כשנוצר תיקו- עוצרים (לא יתכן ששני הצדדים מנצחים, למשל- שלושה X-ים בשורה העליונה ושלושה O-ים בשורה התחתונה). With T1 As --3 posible signs ("-" = empty) (Select '-' IMD Union All Select 'X' IMD Union All Select 'O' IMD), T2 As (Select...
אין תגובות