sql server COLUMNS_UPDATED function
-
זה מחזיר מה שנקרא bitsmask, שזה שיטה להשתמש עם כל סיבית לערך בפני עצמו לפי הסדר.
אח"כ אפשר להמיר את זה למספר ולהפך.
הנה מה שכתוב באנגלית בדוגמה המופיעה בhttp://technet.microsoft.com/en-us/library/ms186329.aspx:/*Check whether columns 2, 3 or 4 have been updated. If any or all columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To test whether all columns 2, 3, and 4 are updated, use = 14 instead of >0 (below).*/
מה שזה אומר שאם יש לך 10 עמודות אז הערכים המתאימים לכל טבלה זה חזקת 2 למיקומה:
0 0 1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024
במקרה שמה באתר באנגלית שונו כל העמודות הללו: שנייה שלישית ורביעית. באינדקס מבוסס אפס זה עמודות 1,2,3.
לפי הטבלה: 1=2, 2=4, 3=8. 2+4+8=14.
איך מפרקים את זה? כמו כל המרה עשרונית לבינארית:
או להשתמש בטבלה כזו או גודלה יותר וכל פעם לחפש את הערך העליון ולהפחית אותו מהערך המקור.
או חלוקה ל2 ובדיקת שאריות כמפורט בויקיפדיה שיטה שנייה: http://he.wikipedia.org/wiki/בסיס_בינארישים לב שאם אתה רוצה לדעת על עמודה ספציפית, אתה יכול להשתמש בפונקציה אנושית יותר:
IF UPDATE (ColumnName)
כעת קראתי את המאמר שבקישור האחרון ואכן הוא מראה דרך טובה יותר, עם פונקציה מובנית זו sys.fn_IsBitSetInBitmask
פונקציה זו תפקידה לנתח bitmask מעצבנים. נגיד אתה רוצה לדעת אם עמודה 15 נמצאת במספר המעצבן שמחזירה הפונקציה COLUMNS_UPDATED,
אז אתה קורא לפונקציה ככהsys.fn_IsBitSetInBitmask(COLUMNS_UPDATED(), 15)
והיא מחזירה אפס אם לא.
עוד שכלול עשה המוכשר שם, זה שימוש בשם העמודה ולא באינדקס שלה. זה יותר נוח (העמודה ההיא שנייה משמאל וגם יציב יותר במקרה שינויים במבנה הטבלה.
בשביל זה הוא השתמש בפונקציה בשם COLUMNPROPERTY. היא מחזירה כל מאפיין שנרצה על כל עמודה ברחבי המסד שניתן כפרמטר. נו? אחד המאפיינים של עמודה זה האינדקס שלה.
איך משתמשים? ככה:COLUMNPROPERTY(OBJECT_ID('Person.Person'), 'ColName', 'ColumnID')
כאשר Person זה גם שם המסד וגם טבלה שבו. ColName זה שם העמודה. ווככה זה מחזיר לנו את הID של העמודה הזו.
פורסם במקור בפורום CODE613 ב26/12/2013 13:06 (+02:00)
-
ראשית תודה ואבדוק הנושא. המושגים שלי בבינאריזציה עדיין לוקים בחסר צריך ללמוד את הנושא הזה אחת ולתמיד.
אני לא רוצה לדעת על עמודה ספציפית, אני צריך לדעת "איזו" עמודה השתנתה זה טריגר כללי שחל על כל הטבלה. אז לעשות מאה איפים ועל כל עמודה שמוסיפים או גורעים או משנים שם לעשות עוד איף זה לא יעיל.
קצת מוזר שמייקרוסופט לא השכילו לעשות פונקציה קטנטנה שתחזיר לי את שם העמודה מה קרה??? למה זה צריך להיות בינארי? הרי כל המחשב זה בינארי, עושים שפת תיכנות כדי לא להתעסק עם הדברים האלו.
שנית בשלב הבא אצטרך להשיג ערך שלפני העדכון ואחרי העדכון, אם אני מבין נכון זה 2 טריגרים שונים after ו Instead כאשר after נותן את הערך שאחרי העדכון ואילו Instead מחזיק ערכים שלפני העדכון.
פורסם במקור בפורום CODE613 ב26/12/2013 13:54 (+02:00)
-
ערכתי את ההודעה, זה ממש לא "גדול" כמו שזה נראה.
אגב אני לא יודע וזוכר בזה כלום אני מריץ מהר חיפושים ברשת וכו'.הצלחה, ותודה על שאתה מכניס אותנו לעוצמה של הטריגרים.
בשולי העניין, הbitmask נמצא גם בתכנות בNET ושאר ירקות.
למשל הרבה מאוד Enum בדוט נט בנויים עם ערכים של חזקות 2 כדי לאפשר להשתמש בכמה מהם.פורסם במקור בפורום CODE613 ב26/12/2013 14:24 (+02:00)
-
אני לא רוצה לדעת על עמודה ספציפית, אני צריך לדעת "איזו" עמודה השתנתה זה טריגר כללי שחל על כל הטבלה. אז לעשות מאה איפים ועל כל עמודה שמוסיפים או גורעים או משנים שם לעשות עוד איף זה לא יעיל.
קצת מוזר שמייקרוסופט לא השכילו לעשות פונקציה קטנטנה שתחזיר לי את שם העמודה מה קרה??? למה זה צריך להיות בינארי? הרי כל המחשב זה בינארי, עושים שפת תיכנות כדי לא להתעסק עם הדברים האלו.
אם תתבונן, תמצא שאין כ"כ דרך נוחה להנגיש את כל העמודות ששונו, או לציין לך אותם.
אם היו נותנים מערך זה היה נוח לך יותר להבין, אבל ממש לא נוח לשימוש (בשביל לבדוק אם המערך מכיל איבר, היית צריך פונקציה או לחפש).
אם השימוש שלך הוא לדעת על כל העמודות ששונו אז בכל מקרה אתה חייב לעשות לולאה אודותיהם, וממילא אתה יוכל להשתמש בפונקציה לעמודה בודדת שהיא קלה ונוחה.פורסם במקור בפורום CODE613 ב26/12/2013 14:28 (+02:00)
-
לולאה על העמודות נשמע לי יותר פשוט, לא יודע למה באמת לא חשבתי על זה קודם, לפעמים כשאתה שוקע במשהו מסובך, אתה מאבד את היכולת לעלות על רעיון פשוט מפשט כדי לפתור אותו בדרך אחרת לגמרי.
ראיתי שלא העלית קוד אני עדיין לא בקי בסינטקס של sql server איך לעשות foreach וכדומה.
תודה.משהו בסיגנון הזה, אין לי זמן לבדוק עד הסוף אני מקוה שעובד:
insert into dbo.LogTable([Contrnt]) select c.name from sys.columns c inner join sys.objects o on c.object_id=o.object_id where (UPDATE (c.name)) and o.name='Questions'
פורסם במקור בפורום CODE613 ב26/12/2013 15:05 (+02:00)
-
ארכיטקט שווה לך לעבור על 8 פוסטים של גדי רשף:
זה הראשון, דפדף קדימה עד לסיום הסדרה.מה שהכי נוגע לענייננו זה הפוסט הזה
http://blogs.microsoft.co.il/gerireshef/2010/05/13/האח-הגדול-עינו-פקוחה-5-מי-שינה-את-הנת/ושלוש שנים (!) אח"כ פשוט בהרבה:
http://blogs.microsoft.co.il/gerireshef/2013/07/16/האח-הגדול-עינו-פקוחה-6-מי-שינה-את-הנת/פורסם במקור בפורום CODE613 ב26/12/2013 15:18 (+02:00)
-
סיכום ביניים לטריגר רגיל:
זה הולך ככה, הטריגר נותן לנו אוסף (! לא רשומה אחת) של שורות עבר (DELETED), ואוסף של שורות חדשות (INSERTED).
שורות העבר הם המחוקות+הערוכות בגירסתם הישנה, והשורות החדשות כוללות שורות שנוספו+שורות נערכו בגריסתם החדשה.
לשתי הטבלאות אין קשר ביניהם, ומוכרחים לעשות JOIN אם רוצים לגשת להשוות. בשביל JOIN כמובן צריך שתהיה עמודת מפתח כל שהיא של עוברת עריכה כי זה שומט את הקשר.
את שם העמודת מפתח זו גם מוכרחים להחזיק ביד בשביל התשאול.הטריגר גם מוכן להצביע לנו על העמודות שנערכו בהם שינויים. אפשר להשיג הן את האינדקס והן את שם העמודה כסטרינג, אבל אין יכולת בכללל לעשות לזה JOIN עם הטבלאות DELETED וINSERTED דלעיל כדי לקבל מידע על ערך ישן וחדש לעמודה זו, זאת משום:
- איננו יכולים לתשאל (בצורה טבעית) עם סטרינג במקום ליטרל של שם העמודה.
- התשאול מביא את חתך לאורך כל השורות, בעוד שבדיקתנו אם עמודה עודכנה היא פר שורה.
פורסם במקור בפורום CODE613 ב26/12/2013 21:22 (+02:00)
-
אגב לתדהמתי אני רואה פתאום שבאקסס 2013 הם עשו אירועים ברמת הטבלה, ושם אתה מקבל בדיוק מה שרצינו ומה שאמרת שאין ב sql server ערך ישן, ערך חדש, ושם השדה בסטרינג.
לא יאומן איזה גורל, מחליטים בשביל האקססאים לעשות שכלולים שאין לך דרך להשיג אותם ב sql server!!!
פורסם במקור בפורום CODE613 ב31/12/2013 17:42 (+02:00)
-
יש אור בקצה המנהרה!!
אפשר להריץ SQL כמחרוזת כזה:EXECUTE ( 'select * from Contacts')
כעת צריך לראות אם אפשר ליצור מחרוזת גנרית שתיבנה על ידי קוד ושבעצם תהיה שאילתת עדכון ובא לציון גואל.
ברור שאפשר וזה ידעתי מתחילה רק שזה ממש לא נראה לי דרך נורמלית.
פורסם במקור בפורום CODE613 ב31/12/2013 19:16 (+02:00)
-
אגב לתדהמתי אני רואה פתאום שבאקסס 2013 הם עשו אירועים ברמת הטבלה, ושם אתה מקבל בדיוק מה שרצינו ומה שאמרת שאין ב sql server ערך ישן, ערך חדש, ושם השדה בסטרינג.
לא יאומן איזה גורל, מחליטים בשביל האקססאים לעשות שכלולים שאין לך דרך להשיג אותם ב sql server!!!
כבר מילתי אמורה בנושא זה רק חבל שמייקרוסופט לקחה את האקסס לכיוון של ה.... עם מאקרו (לך תעשה FOR במאקרו, [לא אמרתי שא"א אבל מעיק]) במקום לכיוון של המתכנתים עם יכולות מורחבות.
פורסם במקור בפורום CODE613 ב31/12/2013 23:25 (+02:00)
-
ארכיטקט, נראה לי שהבעיה היא הסיטואציה שלך, ולא מערכת הDB. למה? ממה שאני מבין בכל מקום, זה לא כ"כ מעניינו של הDB הדברים הללו.
הסיבה שאתה עושה את זה ברמת הDB זה משום שהקליינט שלך הוא אקסס, אבל סביר מאוד שבצורך נורמלי הכי טוב זה SP (יוזר, טבלה, עמודה, שדה חדש) שמכניס את הנתון ומעדכן את הלוג, וכל הבעיה נפתרה.
הסיבה שאני חושב שהDB הוא לא המקום לכאלה דברים, זה העובדה שאין את האפשרות הזאת בצורה פשוטה, ייתכן אמנם שפשוט כולם טפשים אבל בכל אופן.פורסם במקור בפורום CODE613 ב26/01/2014 19:03 (+02:00)
-
-
שכבת לוגיקת הנתונים צריכה להיות עצמאית לגמרי, זה לא משנה מה הקליינט, להיפך בארגון שרוב הליבה שלו היא לוקיגת נתונים, הכל צריך להיות סגור בתוך הדטה בייס, בשביל מה יש דטה בייס???? הרי הכל אפשר לעבוד בעצם עם קובצי טקסט או XML ולעשות את כל הניתוח בקוד... :lol: כמו שהיה לפני 40 וחמישים שנה. הרעיון של דטה בייס זה ליצור שכבת פלדה יצוקה של נתונים, שתהווה את היסוד של הבינה העיסקית, ועליה אתה יכול לבנות כמה UI שרק תרצה ובאיזו טכנולוגיה שתבחר. אז קליק וואן באמת צודק כשאמר שאני צודק... :lol: :lol: :lol:
פורסם במקור בפורום CODE613 ב26/01/2014 21:01 (+02:00)
-
שכבת הפלדה של הנתונים יכולה לכלול את הדטה ביס שיכיל נתונים בלבד ועוד כמה מחלקות קוד שיטפלו בנתונים, כך שזה יחסוך לזה המון זמן לנסות לעשות כל דבר בתוך ה SQL, תעשה בקוד ונגמר הסיפור. וכך גם לא תאבד את ההפרדה בין הממשק לשכבת הנתונים.
פורסם במקור בפורום CODE613 ב27/01/2014 06:48 (+02:00)