דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. ארכיון code613m
  4. לאחר מאבקים עזים: קוד שמתעד כל שינוי בדטה בייס

לאחר מאבקים עזים: קוד שמתעד כל שינוי בדטה בייס

מתוזמן נעוץ נעול הועבר ארכיון code613m
10 פוסטים 3 כותבים 530 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • א מנותק
    א מנותק
    ארכיטקט
    כתב ב נערך לאחרונה על ידי
    #1

    באשכול הזה היה דיון אודות פונקציה שמייקרוסופט כנראה לא סיפקו במזיד או שלא במזיד. בכל אופן נאלצנו לעשות קוד שיוצר מחרוזת sql כטקסט, ואז מממש אותה.
    כמו כל דבר טוב אני עורך את זה כמה פעמים עד להשלמה. כעת ערכתי את הפונקציה (27/01/14 22:13) על מנת לאפשר גם בטריגר של מחיקה, לשמור את כל השדות של הרשומה הנמחקת למי שירצה.

    ראשית יש ליצור טבלת לוג כזאת:

    CREATE TABLE [dbo].[LogTable](
    	[ID] [int] IDENTITY(1,1) NOT NULL,
    	[Content] [nvarchar](max) NULL,
    	[TableName] [nvarchar](40) NULL,
    	[ColumnName] [nvarchar](50) NULL,
    	[RowID] [int] NULL,
    	[OldValue] [nvarchar](max) NULL,
    	[NewValue] [nvarchar](max) NULL,
    	[UserModified] [nvarchar](100) NULL,
    	[date] [datetime] NULL,
     CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
    (
    	[ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    
    ALTER TABLE [dbo].[LogTable] ADD  CONSTRAINT [DF_Log_date]  DEFAULT (getdate()) FOR [date]
    GO
    
    ALTER TABLE [dbo].[LogTable]  WITH CHECK ADD  CONSTRAINT [CK_LogTable] CHECK  (([OldValue]<>[NewValue]))
    GO
    
    ALTER TABLE [dbo].[LogTable] CHECK CONSTRAINT [CK_LogTable]
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'מאמת שלא נכנסים ערכים שווים לטבלה' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'LogTable', @level2type=N'CONSTRAINT',@level2name=N'CK_LogTable'
    GO
    

    לאחר מכן ליצור פונקציה זאת:

    CREATE FUNCTION [dbo].[GetSqlStatementToInsertLogTable]
    (
    	@PROCID int -- משתנה זה מכיל את האידי של הטריגר הוא מוכנס על ידי משתנה מקומי שיש בכל טריגר
    )
    RETURNS nvarchar(max)
    AS
    BEGIN
    
    
    	DECLARE  @TableName sysname ,@Sql nvarchar(max) = ''  , @CurrentRow int = 0 , @CurrentFieldName nvarchar(100)
    	-- מאתר את שם הטבלה שמאחוריה עומד הטריגר שביקש את הפונקציה
    	select @tablename = object_name(parent_id) 
        from sys.triggers where object_id = @PROCID
    	
    	-- טבלה המכילה את כל השדות של טבלה נוכחית
    	declare @FieldsTable table (ColID int, ColumnName nvarchar(50), TableName nvarchar(50))
    	insert into @FieldsTable 
    	select  c.column_id as ColID, c.name as ColumnName, t.name as TableName
    	from sys.all_columns c
    		inner join sys.tables t on t.object_id = c.object_id 
    		where c.is_identity = 0  and user_type_id <> 189 and t.name = @tablename -- אין טעם להכניס אידנטיטי כי הוא לא משתנה אף פעם כמו כן סוג חותמת זמן לא שייך לתעד
     
    
     declare @maxRecords int = (select max (colid) from @FieldsTable)
    	declare @str nvarchar(max)
    	while  @CurrentRow < @maxRecords 
    	BEGIN
        SET @CurrentRow = @CurrentRow + 1
        set @CurrentFieldName = (select ColumnName from @FieldsTable WHERE ColID=@CurrentRow) -- השדה הנוכחי בטיפול
    	-- יוצר את האסקיואל שאמור לטפל בכל שדה ושדה והרוצה יעיין בקוד הדק היטב
    	set @str = N'select ''' +  @TableName + ''',''' + @CurrentFieldName + ''', d.ID, CONVERT(VARCHAR(max), d.' + @CurrentFieldName + '),  CONVERT(VARCHAR(max), i.' + @CurrentFieldName + '), ''' + SYSTEM_USER + ''' from #deleted d  left join #inserted i on i.ID = d.ID where  i.' + @CurrentFieldName + ' <> d.' + @CurrentFieldName + ' or i.ID is null' + iif(@CurrentRow < @maxRecords , ' union all ', '' )
    	set @Sql = CONCAT (@Sql, @str);
    	END	
    
    	-- זהו זה
    	RETURN @Sql
    END
    

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

    SELECT * INTO #inserted
    FROM inserted
    SELECT * INTO #deleted
    FROM deleted 
    declare @Sql nvarchar(max)  = dbo.GetSqlStatementToInsertLogTable (@@PROCID)
    	insert into LogTable (TableName , ColumnName , RowID , OldValue, NewValue ,UserModified)
    	EXECUTE sp_executesql @Sql
    

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

    פורסם במקור בפורום CODE613 ב27/01/2014 19:45 (+02:00)

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

    תגובה 1 תגובה אחרונה
    1
    • רחמיםר מנותק
      רחמיםר מנותק
      רחמים מורחק
      כתב ב נערך לאחרונה על ידי
      #2

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

      פורסם במקור בפורום CODE613 ב27/01/2014 21:11 (+02:00)

      תגובה 1 תגובה אחרונה
      0
      • א מנותק
        א מנותק
        ארכיטקט
        כתב ב נערך לאחרונה על ידי
        #3

        @רחמים

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

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

        GO
        
        /****** Object:  Trigger [dbo].[Contacts_Updated]    Script Date: 27/01/2014 21:37:25 ******/
        SET ANSI_NULLS ON
        GO
        
        SET QUOTED_IDENTIFIER ON
        GO
        
        CREATE TRIGGER [dbo].[Contacts_Updated]
        ON [dbo].[Contacts]
        after UPDATE
        AS
        BEGIN
        
        SELECT * INTO #inserted
        FROM inserted
        SELECT * INTO #deleted
        FROM deleted 
        declare @Sql nvarchar(max)  = dbo.GetSqlStatementToInsertLogTable (@@PROCID)
        	insert into LogTable (TableName , ColumnName , RowID , OldValue, NewValue ,UserModified)
        	EXECUTE sp_executesql @Sql
        
        END
        
        GO
        

        @רחמים

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

        יש מילה GO בסוף הקוד (תיקנתי את זה עכשיו) תמחק אותה ייתכן שהיא עושה את השגיאה, אם לא אז תגיד איזו הודעת שגיאה הוא כותב.

        פורסם במקור בפורום CODE613 ב27/01/2014 21:40 (+02:00)

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

        תגובה 1 תגובה אחרונה
        0
        • רחמיםר מנותק
          רחמיםר מנותק
          רחמים מורחק
          כתב ב נערך לאחרונה על ידי
          #4

          כשאני לוחץ על תיקיית הפונקציות יוצא את התפריט הבא:

          ללא שם.png

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

          לכידה3.PNG

          פורסם במקור בפורום CODE613 ב27/01/2014 21:53 (+02:00)

          תגובה 1 תגובה אחרונה
          0
          • א מנותק
            א מנותק
            ארכיטקט
            כתב ב נערך לאחרונה על ידי
            #5

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

            פורסם במקור בפורום CODE613 ב27/01/2014 22:29 (+02:00)

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

            תגובה 1 תגובה אחרונה
            0
            • רחמיםר מנותק
              רחמיםר מנותק
              רחמים מורחק
              כתב ב נערך לאחרונה על ידי
              #6

              ניסיתי וזה לא עובד, אצלי זה גירסת 2008 כנראה בגלל זה, אגב מה אתה עושה עם לקוחות XP ? מתאים להם ה 2012 ?

              פורסם במקור בפורום CODE613 ב27/01/2014 23:27 (+02:00)

              תגובה 1 תגובה אחרונה
              0
              • א מנותק
                א מנותק
                ארכיטקט
                כתב ב נערך לאחרונה על ידי
                #7

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

                פורסם במקור בפורום CODE613 ב28/01/2014 10:16 (+02:00)

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

                תגובה 1 תגובה אחרונה
                0
                • רחמיםר מנותק
                  רחמיםר מנותק
                  רחמים מורחק
                  כתב ב נערך לאחרונה על ידי
                  #8

                  @ארכיטקט

                  כבר לא יהיה XP בעולם

                  לפי הסקרים XP נמצא היום בכ 35% מהחשבים.

                  פורסם במקור בפורום CODE613 ב28/01/2014 10:24 (+02:00)

                  תגובה 1 תגובה אחרונה
                  0
                  • M מנותק
                    M מנותק
                    magicode
                    כתב ב נערך לאחרונה על ידי
                    #9

                    @רחמים

                    @ארכיטקט
                    כבר לא יהיה XP בעולם

                    לפי הסקרים XP נמצא היום בכ 35% מהחשבים.

                    לפי סטיסטיקה עולמית.

                    http://gs.statcounter.com/#desktop-os-ww-monthly-201212-201401

                    19 אחוז.

                    פורסם במקור בפורום CODE613 ב28/01/2014 17:31 (+02:00)

                    תגובה 1 תגובה אחרונה
                    1
                    • רחמיםר מנותק
                      רחמיםר מנותק
                      רחמים מורחק
                      כתב ב נערך לאחרונה על ידי
                      #10

                      WIN 8 כל כך גרועה? פחות מ 6 אחוז :?:

                      פורסם במקור בפורום CODE613 ב28/01/2014 17:57 (+02:00)

                      תגובה 1 תגובה אחרונה
                      0

                      בא תתחבר לדף היומי!
                      • התחברות

                      • אין לך חשבון עדיין? הרשמה

                      • התחברו או הירשמו כדי לחפש.
                      • פוסט ראשון
                        פוסט אחרון
                      0
                      • דף הבית
                      • קטגוריות
                      • פוסטים אחרונים
                      • משתמשים
                      • חיפוש
                      • חוקי הפורום