en-UShe-IL
You are here:  Blog > new Forums FAQ > Forums FAQ 348
Register   |  Login
Minimize

השאלה וההסבר: השאלה מובאת בצע שחור כשהערות/הארות מופיעות בצבע כחול


אני רוצה לנהל איזשהי טבלת היסטוריה. כלומר, יש לי טבלה, נקרא לה tbl ויש לה טבלת היסטוריה, נקרא לה tbl_hist שמכילה את כל השדות של tbl + מספר שדות נוספים, שהראשון שבהם הוא שדה histID המוגדר כ identity. (המגבלה היא ששדה histID, כמו כל השדות המיוחדים של טבלת ההיסטוריה, יהיו ראשונים ברשימת השדות).

* אני לא מבין למה הכוונה "ראשונים ברשימת השדות". אין משמעות לסדר השדות ובכל שליפה או הכנסת נתונים או כל פעולה אתה יכול לקבוע את הסדר לבד. אני מאוד לא ממליץ לעבוד עם כוכבית (לזהירות נוסיף "כמעט") בשום מקרה.

ההיסטוריה מנוהלת דרך טריגרים על טבלת tbl שאמורה לבצע Insert ים לטבלת tbl_hist על בסיס התנועה שבוצעה בטבלה. עד כאן אני מקווה שהייתי מספיק ברור (וזה גם בטח נשמע טריוויאלי). הבעיה מתחילה שמבנה הטבלאות יכול להשתנות מידי פעם, ולכן אני לא רוצה לציין בפקודות ה insert את שמות השדות בטבלאות, אלא להסתמך על כל השדות select * from וכו'

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

הכי פשוט היה לכתוב משהו בסגנון:

insert into tbl_hist select 'act' as action, 'me' as modifier, t.* from tbl t

אבל מאחר והשדה הראשון ב tbl_hist הוא identity, הפקודה נכשלת כי אני לא יכול לדרוס את הערך. ניסיתי להוסיף סתם מספר, כלומר

insert into tbl_hist select 1 as histID, 'act' as action, 'me' as modifier, t.* from tbl t

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

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

כל המשמעות של שדה מסוג זה הוא שהנתונים מוכנסים לבד אוטומטית על ידיד השרת. למה אתה מכניס בכלל נתונים לשדה זה? למה לא פשוט לרשום שאילתת INSERT הכי פשוטה (כזו שלומדים בשיעור שני של SQL :-) מייד אחרי שלומדים שאילתת SELECT)

בוא נדגים את הנושא ונציג פתרון ספציפי לבעיה:

/****************************************************** רקע */

-- נעבור לעבוד במסד הנתוןנים של המשחקים שלנו

use QQ

go

 

-- נכין לנו את הרקע על ידי הגדרת טבלה שהיא הטבלה הפעילה

declare @Tbl1 as table (

      [s] nvarchar(10),

      [d] nvarchar(10),

      [f] nvarchar(10),

      [g] nvarchar(10),

      [h] nvarchar(10)

)

-- נכניס כמה נתונים לטבלה רק לשם ההדגמה

insert @Tbl1

select 's','a','e','j','z' union

select 'd','a','r','h','x' union

select 'f','s','t','g','c' union

select 'g','d','y','f','v' union

select 'h','d','u','d','b' union

select 'j','f','i','s','n' union

select 'a','z','o','a','m'

 

-- נגדיר את הטבלה של הארכיון שלנו

declare @tbl_hist as table (

      [histID] int IDENTITY(1,1) NOT NULL,

      [action] nvarchar(10),

      [modifier] nvarchar(10),

      [field1] nvarchar(10),

      [field2] nvarchar(10),

      [field3] nvarchar(10),

      [field4] nvarchar(10),

      [field5] nvarchar(10)

)

 

/************************************************ הפתרון */

-- והנה כל הפתרון בפשטות:

Insert @tbl_hist

-- כאן היתה רשימה של כל השדות שרוצים לעדכן

([action], [modifier] ,[field1],[field2],[field3],[field4],[field5])

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

-- אין חובה הלכניס נתונים לכל השדות כמובן אלא רק לשדות שהגדרנו מעל שאנו מכניסים נתונים אלהם

select 'act','me',* from @Tbl1

 

/***************************************** נציג תוצאות לבדיקה **/

select * from @tbl_hist