sql server get identities

Mr Chelo

New member
sql server get identities

נתקלתי בבעיה שאני צריך לדעת את ה Id`s החדשים שנוספו כתוצאה מ:


INSERT INTO dbo.tblX
(
fieldX
)
SELECT fieldY
FROM dbo.tblY
WHERE Id =3


במקרה נוספו כמה שורות, האם יש דרך לדעת מה הם ה id`s החדשים?
(ל tblX יש מפתח רץ)
scop_identity במקרה הזה לא ממש יעזור לי כי זה יתן לי רק Id אחד.

תודה.
 

pitoach

New member
האם זו פעולה חד פעמית או קבועה?

אם מדובר באירוע חד פעמי למשל שחזור נתונים אז אפשר לעבוד עם קבצי הלוג ולקרוא משם את הנתונים ששונו

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

* נסה לאפיין את המצב יותר לעומק ואולי נמצא משהו שמתאים לך יותר מדוייק
 

גרי רשף

New member
נסה להשתמש גם ב-RowCount@@

משתנה המערכת @@RowCount מציין כמה שורות השתנו בפקודה האחרונה,
ואם אתה יודע את האחרון - Scope_Identity - ואת ה-Increment (בדרך כלל 1) תוכל לחשב את כולם.
 

pitoach

New member
זה נותן נתון מספרי של כמות אבל לא את הערכים

של ה ID ששונו (זו הבקשה להבנתי)

אני לא בטוח שזה משהו שאפשר לסמוך על התוצאות שלו.

אם יש יותר ממשתמש אחד אז החישוב של Scope_Identity פחות RowCount לא בהכרח יוביל ל ID-יים הנכונים (בשלב הבא של השליפה). באמצא יכולים להיות ID-ים שהכניס משתמש אחר תיאורטית. לכן בשליפה שלהם לפי הנתונים האלו עלולים לקבל ID שמישהו אחר הכניס

* אלא אם יש נעילות או משהו דומה
 

pitoach

New member
רעיון יפה


 

Mr Chelo

New member
בעיה קטנה או שלא,

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

pitoach

New member
צודק בהחלט (אני לא רשמתי פתרון יפה אלא

צודק בהחלט (אני לא רשמתי פתרון יפה אלא רעיון יפה
)

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

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

לגבי הבעיה אתה צודק: החלק של המחיקה יוצר בעיה רצינית מפני שהשאילתה הבאה בתור מוחקת את הנתונים ולכן אתה לא יכול לעבוד עם הנתונים הקודמים בשלב הבא כדי לדעת מה היו ה ID-ים שאתה מחפש אחר כך.

* בוא נחבר את הרעיון הזה עם הפתרון ששמתי מעל ונקבל פתרון שלם גם בשיטה של שימוש ב OUTPUT

- אל תמחוק את הנתונים אלא תשאיר אותם בטבלה שמתעדת את הפעולות MyInputIdentityTable .
- מכיוון שעתה אנחנו אנחנו לא מוחקים את הנתונים והטבלה קבועה יהיה עלינו לזהות בהמשך איזה נתונים בטבלה הגיעו משאילתה מסויימת. את זה נבצע את לטבלה הקבועה שלנו MyInputIdentityTable נוסיף עמודה או 2 שיאפשרו לנו זיהוי. למשל עמודה של מי המשתמש שהכניס את הנתוניםן וכן זמן תחילת הפעולה (ערך שנקבע כקבוע לפני תחילת הפעולה). את הנתונים האלא נעביר בפעולה של ה INSERT לטבלת התיעוד שלנו וכך נוכל תמיד לשלוף גם אחורה איזה ID-ים הוכנסו על ידי כל משתמש בכל פעולה (זוהי טבלת לוג למעשה ויש לנהל אותה בהתאם)

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

גרי רשף

New member
השירשור נתן לי השראה לפוסט

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

בנוסף- הפתרון עם ה-Output בהחלט יפה!

בקיצור- החכמתי.

http://blogs.microsoft.co.il/blogs/gerireshef/archive/2012/05/09/identity-insert.aspx
 

Mr Chelo

New member
בסוף העברתי את פתרון לקוד

אולי פחות יעיל ומהיר אבל הרבה יותר קל לעבד את נתונים.
תודה על העזרה
 
למעלה