I have a table Training having column T_StartDate and T_EndDate and so on. Now i want if saved T_EndDate matches with Today's Date , I want record of that column should be deleted by itself. for this i have write some code in procedure but i think this would not work as expectation as procedure can not fire up automatically.
So for this issue i read from internet that i need a trigger to do such functioning. But do not have much of idea about trigger.
So please tell me how could i do this?
Also i am attaching a picture for my table so that you guys understand the structure.
Thanks in advance
Just add a computed column:
alter table Training add IsValid as (case when t_enddate < cast(getdate() as date) then 1 else 0 end)
You can then access the table using this column or using a view:
create view v_Training as
select t.*
from Training
where IsValid = 1;
You can then delete the rows at your leisure -- once per month, once per week.
Otherwise, you need to set up a job to run at exactly midnight. If not, there will be a period of time when the data will not be valid. And, if you miss the update for some reason, you could have problems.
Related
I have a two table scenario with a typical parent / child relational setup:
tblGroup - idGroup (autonumber, PK); GroupName (Short Text), Rank (Number)
tblRange - idRange (autonumber, PK), idGroup (FK -> tblGroup.idGroup), RangeName (Short Text), Rank (Number)
What I am doing on the parent (tblGroup) table is using a data macro to add the rank using the BeforeChange event:
IF
IsInsert
SetField - Rank
- DMAX(Rank, [tblGroup])+1
This works nicely and I can happily use a parametized INSERT query to add rows to the table and not have to worry about duplicate ranks and so forth.
What I would like to be able to do but cannot figure out how, is to have a data macro do the same thing for the child (tblRange) table, with the rank being set to the new highest for the parent group the child record belongs to.
If I use the same DMAX approach as I have above I am supposed to be able to set a criteria as a third option, acting like a where clause, to limit the lookup / calculation. How can I refer to the specific idGroup I am working with in tblRange in the macro? I cannot seem to figure out how to reference the new records value for this in the macro.
Something like DMAX(Rank, [tblRange], ???How_to_refer_to_idGroup_Properly???)+1
Any help greatly appreciated
Cheers
The Frog
I figured out a way to do this. Thankyou caffeinated beverages!
The reason for the strange error messages is due to limitations in the Data Macro processing, specifically in the BeforeChange event. The solution is as follows:
Create a query that selects MAX rank (MaxRank) and GROUP BY for the idGroup (ParentID)
The resultant query produces two columns of data: [MaxRank] and [ParentID]
There will be a row for every idGroup with the maximum Rank for each
Create a BeforeChange data macro
Set the following:
IF IsInsert
LookupRecord
Lookup Record In - qryGetMaxRank (or whatever you called your query)
WHERE - [qryGetMaxRank].[ParentID] = [tblRange].[idGroup]
Set Field
Name - [tblRange].[Rank]
Value - [MaxRank] + 1
The BeforeChange event cannot handle parameters for a query, and I am guessing that this applies in some form the to DMAX function here too. The use of a query that does not use any parameters, and then using the LookupRecord WHERE clause to do the filtering provided the single row result needed. The [MaxRank] value from the returned result is then able to be used to set a new value for the field.
Bit of a workaround but it does allow someone to work with the data either through a form or through the datasheet view and not create a problem.
**In answer to if this is a multi-user DB - it is not. It is just me working with it. If / when the solution is scaled up to something requiring multi-user I will likely recreate the BE in SQL Server or MySQL and use stored procedures for all data I/O. Happy to keep Access as the FE and compile into an application (using the runtime for clients), but I am a fair way off from having to do that yet. Very early stages of development at this time.
Cheers to everyone for the pointers. They helped me figure this out. Hopefully this will be of use to someone else in the future.
PS: If you need to use a parametrized query in a data macro it looks like the best bet is with the AfterInsert event or AfterUpdate event as they can support parameters.
I am looking for an Idea to handle data in DB directly.
Here is my use case
I have table “EVENT_REGISTERED” with column (ID, Event_name,Event_DateTime)
I want to display the EVENT_REGISTERED in the fronted end whose date and time is not passed. i.e. I want to display only Upcoming event not Historical events.
Of course this can be handle with JS code before displaying.
But What I want is there should be some sort of a trigger which will delete the Instance form the “EVENT_ REGISTERED” table and copy it to another Table “HISTORICAL_EVENT”
I cannot Create an MY SQL EVENT to do this as it like batch job and I cannot run this every 5 mins as there can be more than 10000 rows in there.
I see Trigger option as well, I am not sure how to use this as it says that it will be activated after the specific action is executed. Here the specific action is CURRENT_DATETIME == EVENT_DATETIME.
Can anybody give me a direction or any sort of alternative way to achieve this?
**I am not an Expert of MySQL*
Thank you
Regards
Prat
Don't start moving rows between tables. Simply run a query:
select er.*
from event_registered
where er.event_datetime > now();
With an index on (event_datetime), performance should be fine.
Thank you all in advance for any help. I'm Still very new to access and have no idea where to start to find a solution.
What I am trying to do is to auto populate a field in my table called "Period". I would like to have it use the "Activity_Date" to look into a different table that has date ranges that reference to the correct period. Based on which "Period" the "Activity_Date" falls under will return the correct "Period". I've tried using calculated data type and queries and I feel no closer to an answer than when I started.
Thanks again for your time.
I would question why you NEED to populate the field period in your table.
In short, I wouldn't bother.
The period it is in can be derrived from the activity date field that is in the same record.
So you can write select statements that calc the period for the record in your MyTable as required.
SELECT TableWithPeriods.period, MyTable.activity_date
FROM MyTable
LEFT JOIN TableWithPeriods
ON MyTable.activity_date
BETWEEN TableWithPeriods.StartDate
AND TableWithPeriods.EndDate
If you need to access the period a lot then there is an argument for keeping a period value in the MyTable in step with the TableWithPeriods.
Keeping in step could be akward though as what if someone changes one of the period 's dates?
Keeping in step might mean writing a bit of SQL to update ALL MyTable rows that wither do not have the period set or when the period is now different.
A VBA update statement will look a bit like the SELECT above.
Or
you could use database the onchange macros that respond to data being added or updated in the MyTable (and the TableWithPeriods, if users can change dates).
Anyway, there's my opinion. I would NOT copy the value over.
PS I'm not 100% sure about the SQl I gave above, this might work though
SELECT TableWithPeriods.period, MyTable.activity_date
FROM MyTable
LEFT JOIN TableWithPeriods
ON ( MyTable.activity_date >= TableWithPeriods.StartDate
AND MyTable.activity_date <= TableWithPeriods.EndDate )
I have the following problem to solve. I need rows inserted into a "reservations" table to, upon insertion, set a timer for themselves and then check a flag within this newly created row some minutes later to see if it has changed from "pending" to "completed" (which would be caused by user action in the intervening period) and if still "pending" to remove themselves from the table.
The idea here is that people are making reservations and the act of beginning the reservations process adds this row, however, if they fail to complete the purchase over a period of time I want to remove the rows to make the reservations (of which there is a finite amount) available to other consumers.
So, I've been looking at events and triggers and I get the concept for both, but what I'm failing to find is a way for the trigger to pass *this row's id to the event so that when the event fires it only looks at the relevant row because I don't want it to notice *all the rows that might be "pending" since there may have been newly created "pending" rows by other consumers for other reservations in the intervening period, and I obviously don't want to mess with those until their respective timers have elapsed.
So... what I am hoping for (in pseudo) is...
/*EVENT*/
CREATE EVENT IF NOT EXISTS delete_abandoned_pending_purchase
ON SCHEDULE AT CURRENT_TIMESTAMP + 5 minutes
DO
delete from tickets where state = 'PENDING' and id = [MY ROW ID]
and then...
/*trigger*/
CREATE TRIGGER remove_if_unused
AFTER INSERT ON `tickets` FOR EACH ROW
begin
[call delete_abandoned_pending_purchase with row_id MY_NEW_ROW_ID]
end
I'm guessing maybe I need to make a stored procedure that takes a parameter and then pass that row ID as the param? Or perhaps there's a more straight forward way... I'm just failing to find the syntax for this and would love some guidance. Obviously I can handle this in the business logic that wraps this data interaction, but felt that this was a more elegant approach.
[EDIT]
reading more about this
"There is no way to pass parameters directly to or from events; however, it is possible to invoke a stored routine with parameters within an event".
But the suggestion there is to call a stored procedure and pass it a param. However, my problem is that I don't see how to get *at the row.id in the event to pass to the stored proc. I feel like I must be missing something obvious... how can events not have access to specific row ids?
[EDIT EDIT]
so, based this I'm sensing that this is actually not doable in mySQL... that's a bummer and also quite surprising. Seems like a really obvious thing to want to do.
I'll leave the question open and see if anyone chimes in with a clever alternative.
I would recommend you do this via a script, less complexity and more control. Something like below:
MaxSleep=300 # In seconds SleepTime=MaxSleep
while (1) {
sleep SleepTime; delete from TheTable where reserved = 'pending' and the_timestamp >= Current_Timestamp; SleepTime='mysql
'select the_timestamp from TheTable where reserved = 'pending' order
by the_timestamp limit 1"
if SleepTime is null then SleepTime= MaxSleep
}
You could just do an event that checks against the whole table, should be fast if it is indexed correctly and then the business logic is in the DB. Perhaps use a minute as the check then max pending transaction is 6 Minutes if you have a 5 minute timeout.
CREATE EVENT delete_abandoned_pending_purchase
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 Minutes
DO
BEGIN
delete from TheTable where reserved = 'pending' and the_timestamp >= Current_Timestamp;
END
This may be a stupid question but is it possible to store a count query in a field in a table such that when the result of the count changes the result will update itself?
Thread(ThreadID,NumMessages)
Message(MessageID,ThreadID,MessageText,PreviousMessage)
I want to update the Thread.NumMessages field any time a message with the corresponding ThreadID gets added or removed. I know I can do this by incrementing/decrementing the Thread.NumMessages field of by using a count query
SELECT COUNT(*), FROM SCHEMA.Message WHERE ThreadID='SOMETHREADID'
But is there anyway of setting up the NumMessages field so this is kept up to date without it being done explicitly at every addition and delete?
Thanks
Graeme
yes, you can use a view as the implementation of your Thread table.
http://dev.mysql.com/doc/refman/5.1/en/create-view.html
Create view thread_view
select
count(*) as NumMessages,
threadID
from message
group by threadID
Triggers!
You're wanting a trigger. This should help you with your searching (knowing what to look for is half the battle). http://www.databasedesign-resource.com/mysql-triggers.html
Basically, a trigger fires any time a designated event (such as insert) on a table is tripped, and executes a stored procedure.
your stored procedure would then check to make sure it's something it cares about (you can add all sorts of logic here), then does something (increment that value?) before MySQL executes the original query that triggered it in the first place.
http://www.roseindia.net/mysql/mysql5/triggers.shtml