Altering timestamp

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dbrewerton
    New Member
    • Nov 2009
    • 115

    Altering timestamp

    Hello everyone, hope you are all doing fine. What I'm attempting to do and have been tearing my hair out over for the last few weeks is trying to update timestamps in my MySQL database when this data gets fed in by an XML data feed. The data comes in as a group of slices. The number of slices per feed could be different so I have to dynamically find a way to take my existing stored procedure and expand on it. The problem I have is the timestamps can be incorrect. I am capturing the time/date that the record gets written to the database in a separate field. What I'm trying to do is:

    1. Count the number of records that come in from the raw XML feed.
    2. Compare the time difference between two of the record slices.
    3. Take the last record of the batch and apply the time/date in the database.
    4. Apply that time/date stamp less the difference for the previous records.

    Onto my Stored Procedures:

    There are two SPs involved, one is named parse_raw and the other get_node_conten t. The SP parse_raw calls get_node_conten t to break the raw XML into individual slices.

    Code:
    ###################
    delimiter ;
    
    DROP PROCEDURE IF EXISTS `parse_raw`;
    DELIMITER $$
    CREATE PROCEDURE `parse_raw`()
    BEGIN
    
    DECLARE x_id BIGINT;
    DECLARE xtext text;
    DECLARE useless1 text;
    DECLARE useless2 text;
    DECLARE x_device_string varchar(30);
    DECLARE x_device_id BIGINT;
    DECLARE slice_text text;
    DECLARE time_text text;
    DECLARE new_slice_id BIGINT;
    DECLARE msmnt_tag VARCHAR(30);
    DECLARE value_text text;
    DECLARE x_msmnt_type_id BIGINT;
    
    #Loop for all rows in table
    main_loop: LOOP
    
    	#Get a row, if we can't we're done
    	SET x_id = -1;
    	SELECT ewise_raw_data_in.raw_id, ewise_raw_data_in.raw_data_xml FROM ewise_raw_data_in LIMIT 1 INTO x_id, xtext;
    	IF (x_id = -1) THEN
    		LEAVE main_loop;
    	END IF;
    
    
    	CALL get_node_content(xtext, 'energywise', xtext, useless1, useless2);
    
    	CALL get_node_content(xtext, 'device', x_device_string, useless1, xtext);
    
    	set x_device_id = 0;
    	SELECT ewise_device.device_id FROM ewise_device WHERE ewise_device.device_string = x_device_string INTO x_device_id;
    
    	IF (x_device_id = 0) THEN
    	INSERT INTO ewise_device VALUES (default, NULL, x_device_string, NULL, NULL, NULL, NULL);
    	SELECT LAST_INSERT_ID() INTO x_device_id;
    	END IF;
    
    	WHILE length(xtext) > 0 DO
    	CALL get_node_content(xtext, 'slice', slice_text, useless1, xtext);
    
    	IF length(slice_text) >0 THEN
    		CALL get_node_content(slice_text, 'time', time_text, useless1, slice_text);
    		INSERT INTO ewise_slice VALUES (default, x_device_id, time_text);
    		SELECT LAST_INSERT_ID() INTO new_slice_id;
    
    		WHILE length(slice_text) > 0 DO
    			set x_msmnt_type_id = 0;
    			CALL get_first_node_name(slice_text, msmnt_tag);
    			CALL get_node_content(slice_text, msmnt_tag, value_text, useless1, slice_text);
    			IF length(msmnt_tag) >0 THEN
    				SELECT ewise_msmnt_type.msmnt_type_id FROM ewise_msmnt_type WHERE ewise_msmnt_type.msmnt_type_code=LEFT(msmnt_tag,8) INTO x_msmnt_type_id;
    				IF (x_msmnt_type_id = 0) THEN
    					INSERT INTO ewise_msmnt_type VALUES (default, LEFT(msmnt_tag, 8), NULL, NULL);
    					SELECT LAST_INSERT_ID() INTO x_msmnt_type_id;
    				END IF;
    				INSERT INTO ewise_slice_msmnt VALUES (default, new_slice_id, x_msmnt_type_id, value_text); 
    			END IF;
    		END WHILE;
    
    	END IF;
    
    	END WHILE;
    
    	#Delete the data row
    	DELETE FROM ewise_raw_data_in WHERE ewise_raw_data_in.raw_id=x_id;
    
    END LOOP main_loop;
    END
    $$
    
    ###################
    delimiter ;
    
    DROP PROCEDURE IF EXISTS `get_node_content`;
    DELIMITER $$
    CREATE PROCEDURE `get_node_content`(IN in_xml text, IN in_node_tag VARCHAR(30), OUT node_contents text, OUT prev_string text, OUT post_string text )
    BEGIN
    
    DECLARE node_start int;
    DECLARE node_content_start int;
    DECLARE node_end int;
    DECLARE node_tag_start varchar(30);
    DECLARE node_tag_end varchar(30);
    
    set node_tag_start = concat('<',in_node_tag,'>');
    set node_tag_end = concat('</',in_node_tag,'>');
    
    set node_start = locate(node_tag_start, in_xml) ;
    set node_end = locate(node_tag_end, in_xml);
    set node_content_start = node_start + length(node_tag_start);
    
    set node_contents = if(node_start=0,'', if(node_end <= node_content_start, '', substring(in_xml, node_content_start, node_end - node_content_start)));
    set prev_string = if(node_contents = '','',substring(in_xml, 1, node_start-1));
    set post_string = if(node_contents = '','',substring(in_xml, node_end + length(node_tag_end), length(in_xml))); 
    
    END
    $$
    I have been able to get the time stamp to be set but it sets on all the slices. The record format is like this:

    (Line breaks for clarity, actual record has none)
    Code:
    <energywise>
    <device>718270087784420</device>
    <slice>
    <time>20000101050438</time>
    <t1>69.574</t1>
    <t2>64.287</t2>
    <c1>0</c1>
    </slice>
    <slice>
    <time>20000101050938</time>
    <t1>73.737</t1>
    <t2>63.275</t2>
    <c1>0</c1>
    </slice>
    </energywise>
    Any assistance from the GURUs here would be most appreciated, thank you in advance!
  • code green
    Recognized Expert Top Contributor
    • Mar 2007
    • 1726

    #2
    trying to update timestamps in my MySQL database
    I don't quite follow what you are trying to achieve, considering there is no UPDATE query in your code
    I have been able to get the time stamp to be set but it sets on all the slices
    Try to use correct terminology. A timestamp has a definite meaning in computer language and to SET a timestamp is meaningless.
    I'm sorry if I have mis-understood, it may be you have posted too much.
    Could you narrow the code down to where you think the problem is?

    Comment

    • dbrewerton
      New Member
      • Nov 2009
      • 115

      #3
      Altering timestamp

      Ok, let me clarify where the problem is and what I'm trying to do. In the raw data feed, I'm getting data in groups. Essentially, this would be fine if the devices actually had the correct date and time but they do not. When these devices first come online, they start at 01/01/2000 00:00:00. The table involved is:

      Code:
      raw_data_in (where data feeds into)
               |--------> raw_id
               |--------> raw_data_xml
               |--------> raw_data_datetime
      Data gets parsed out to ewise_slice and ewise_slice_msm nt

      Code:
      ewise_slice
               |--------> slice_id
               |--------> device_id
               |--------> slice_timestamp (gets this from the raw parsed data)
      
      ewise_slice_msmnt (non-related but including so schema is understood)
               |--------> slice_msmnt_id
               |--------> slice_id
               |--------> msmnt_type_id
               |--------> msmnt_value
      Now, the one time I actually got it to set the time and date of each record, it set them all to the raw_data_dateti me. Zeroing in on the section I'm referring to is:

      Code:
      	IF length(slice_text) >0 THEN
      		CALL get_node_content(slice_text, 'time', time_text, useless1, slice_text);
      
      		SELECT TIMESTAMPDIFF(SECOND,time_text,RealTime) INTO NewTime;
      		SELECT date_Add(time_text,INTERVAL NewTime SECOND) INTO GoodTime;
      		INSERT INTO ewise_slice VALUES (default, x_device_id, GoodTime);
      		SELECT LAST_INSERT_ID() INTO new_slice_id;
      I hope this helps clarify a little what I'm trying to do. Sorry for any confusion from my first posting.

      Comment

      • dbrewerton
        New Member
        • Nov 2009
        • 115

        #4
        Altering timestamp

        I just noticed that the time of these records is fine, it is the date that is wrong. Is there a method of changing the date of the record when it gets inserted since the SP takes the returned record from get_node_conten t? I'll see what I can uncover here to try to resolve my problem on my own. If anyone can think of some way to change only the date, feel free to fire away :)

        Comment

        • dbrewerton
          New Member
          • Nov 2009
          • 115

          #5
          I thought that was the case but I'm wrong. Can someone help me please?

          Comment

          • code green
            Recognized Expert Top Contributor
            • Mar 2007
            • 1726

            #6
            I am sorry but I am stuggling to understand.
            It may help if you were more precise as to which time you are referring to.
            if the devices actually had the correct date and time but they do not
            OK I can see the "device" time is no use
            Now, the one time I actually got it to set the time and date of each record, it set them all to the raw_data_dateti me
            Which was parsed from the XML? You didn't mention raw_data_dateti me in your first post.
            Nor is it mentioned in the SQL you quote
            Code:
            SELECT TIMESTAMPDIFF(SECOND,time_text,RealTime) INTO NewTime; 
                    SELECT date_Add(time_text,INTERVAL NewTime SECOND) INTO GoodTime; 
                    INSERT INTO ewise_slice VALUES (default, x_device_id, GoodTime);
            You seem to be trying to manipulate STRING values from XML.
            This is fine but MySQL datetime functions don't understand strings.
            They must be converted into DATE or TIME data types first.
            Is this the real problem or have I lost the plot?
            Can you make use of system time = NOW().
            You can set DATE and TIME data type fields default to NOW(),
            which is set at time of INSERT or UPDATE

            Comment

            • dbrewerton
              New Member
              • Nov 2009
              • 115

              #7
              Altering timestamp

              I decided to attack this from a different angle. Instead of my trying to fight with the values before they get inserted, I have instead decided to change the time stamp after all the values from the newly inserted row. What I'm doing now is calling out to a newly created SP called fixmytimes and I'm passing three values to it. This is the result of a lost night of sleep thinking about attacking the problem.

              This SP should work fine, however I have run into a snag trying to create and use counters to keep track of my looping. Here is my new SP which will do the job, I just need a little help with using the counters. MySQL barks at me saying:

              "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE counter set mycount = mycount+1"

              Obviously I declared something incorrectly or my syntax is whack.

              Code:
              ###################
              delimiter ;
              
              DROP PROCEDURE IF EXISTS `fixmytimes`;
              DELIMITER $$
              CREATE PROCEDURE `fixmytimes`(IN LAST_INSERT_ID text, IN RealTime text, IN count text)
              BEGIN
              
              declare time1 text;
              declare Timevar text;
              declare firstrec text;
              declare mycount text;
              declare fixedtime text;
              
              SELECT MAX(slice_id), slice_timestamp AS time1 from ewise_slice;
              SELECT timestampdiff(MINUTE,time1,RealTime) INTO Timevar;
              SELECT MAX(slice_id) - count INTO firstrec;
              
              while mycount > count
              UPDATE counter set mycount = mycount+1
              
              UPDATE ewise_slice set slice_timestamp = 
              SELECT date_Add(ewise_slice.slice_timestamp,INTERVAL Timevar MINUTE) where ewise_slice.slice_id = firstrec;
              
              UPDATE counter set firstrec = firstrec+1
              END WHILE
              
              END
              $$
              
              ###################

              Comment

              • code green
                Recognized Expert Top Contributor
                • Mar 2007
                • 1726

                #8
                I am not too hot with SP syntax but should it not be
                Code:
                while mycount > count DO
                UPDATE counter set mycount = mycount+1

                Comment

                • dbrewerton
                  New Member
                  • Nov 2009
                  • 115

                  #9
                  I'll try that and report back, thanks.

                  Comment

                  • dbrewerton
                    New Member
                    • Nov 2009
                    • 115

                    #10
                    Well, got further down. Now its squawking about this line:

                    UPDATE ewise_slice set slice_timestamp = SELECT date_Add(ewise_ slice.slice_tim estamp,INTERVAL Timevar MINUTE) where ewise_slice.sli ce_id = firstrec;

                    Gives me:

                    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE ewise_slice set slice_timestamp = SELECT date_Add(ewise_ slice.slice_tim ' at line 17

                    Comment

                    • code green
                      Recognized Expert Top Contributor
                      • Mar 2007
                      • 1726

                      #11
                      Missing semi-colon?
                      Code:
                      while mycount > count DO 
                      UPDATE counter set mycount = mycount+1 ;

                      Comment

                      • dbrewerton
                        New Member
                        • Nov 2009
                        • 115

                        #12
                        That was a good catch! Now its actually getting to the meat and potatoes of the SP. The calculation is being hit now but I'm getting a syntax error.

                        #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT date_Add(ewise_ slice.slice_tim estamp,INTERVAL Timevar MINUTE) where ewise' at line 18

                        Comment

                        • code green
                          Recognized Expert Top Contributor
                          • Mar 2007
                          • 1726

                          #13
                          Sub-queries need to be in brackets
                          Code:
                          UPDATE ewise_slice set slice_timestamp =  
                          (SELECT date_Add(ewise_slice.slice_timestamp,INTERVAL Timevar MINUTE) where ewise_slice.slice_id = firstrec);
                          These are basic syntax errors that you should be picking up yourself

                          Comment

                          • dbrewerton
                            New Member
                            • Nov 2009
                            • 115

                            #14
                            Man, shows how much lack of sleep can impact query writing...thank s :)

                            Comment

                            • dbrewerton
                              New Member
                              • Nov 2009
                              • 115

                              #15
                              Ok, the first part of my stored proc is ok. I'm running into trouble with the SP that changes the datetime value on my table ewise_slice. Just for testing I have set hard coded values where my variables would normally be. The main problem I have is the darned thing isn't doing anything. Can one of you gurus please take a look and shed some light on why this procedure wouldn't function? I would think MySQL would have some type of echo on function or something similar for verbose output... Thanks.

                              ############### ####
                              delimiter ;
                              DROP PROCEDURE IF EXISTS `fixmytimes`;

                              DELIMITER $$
                              CREATE PROCEDURE `fixmytimes`()
                              BEGIN

                              declare time1 text;
                              declare Timevar INT;
                              declare firstrec INT;
                              declare mycount INT;
                              declare fixedtime text;
                              declare count INT;
                              declare RealTime text;

                              SET RealTime = '2009-11-02 13:25:32';
                              SET count = 10;
                              set firstrec = 0;
                              set mycount = 0;

                              SELECT MAX(slice_id), slice_timestamp AS time1 from ewise_slice;
                              SELECT timestampdiff(M INUTE,time1,Rea lTime) AS Timevar;
                              SELECT MAX(slice_id) - count AS firstrec;

                              while mycount < count DO
                              set mycount = mycount+1;

                              UPDATE ewise_slice set slice_timestamp =
                              (SELECT date_Add(slice_ timestamp,INTER VAL Timevar MINUTE)from ewise_slice where slice_id = firstrec);

                              set firstrec = firstrec+1;
                              END WHILE;

                              END
                              $$

                              ############### ######

                              Comment

                              Working...