Stored procedure to run a query based off timestamp in table - sql

I'm trying to write a procedure where the query will only run if the table has been updated at a certain time.
There is actually a timestamp in the table so I just need to check something like
IF table.update = GETDATE() THEN …
I'm not even sure where to start here.
Can anyone point me in the direction of a place where I can learn about stuff like this, or show me which functions I need to use?

You need to start by looking at how to use Database JOBs.
Since no stored procedure can start by itself.
Inside the Job, you can define how often and when stored procedure run.
The code inside the job can be simple SQL.
OR
You can create an update Trigger on the table. And inside the trigger base on the time call the stored procedure.
Update:
Just saw your latest comment. I have a similar app in my company. We use a Database Job to send a batch of auotmated emails on specific time everyday.

You need a trigger, in the UPDATE method, and you can have it run when it is saved in a separate table.
The new table must have the primary key and the time stamp with the GETDATE () method.
To Implement the Trigger:
create trigger trTriggerTest on tableName after update
As
Begin
set nocount on;
INSERT INTO TimeRegister(Id, date, ...) VALUES (#Id, GetDate(), ...);
end
go
To register en new table:
INSERT INTO TimeRegister(Id, date, ...) VALUES (#Id, GetDate(), ...);
Documentation: Trigger

Related

What can I use instead of an update trigger?

I have an update trigger in SQL Server and I want to remove this trigger and make update operation with a stored procedure instead of the trigger. But I have UPDATE(end_date) control in update trigger.
What can I use instead of below UPDATE(end_date) control? How can I compare old and new end_dates in stored procedure efficiently?
Update trigger
ALTER TRIGGER [dbo].[trig_tbl_personnel_car_update]
ON [dbo].[tbl_personnel_cars]
FOR UPDATE
AS
IF (UPDATE(end_date))
UPDATE pc
SET pc.owner_changed = 1
FROM tbl_personnel_cars pc, inserted i
WHERE pc.pk_id = i.pk_id
Sample updated script in stored procedure
ALTER PROCEDURE [dbo].[personnel_car_update]
(#PkId INT)
UPDATE tbl_personnel_cars
SET end_date = GETDATE()
WHERE pk_id = #PkId
I update tbl_personnel_cars table inside many stored procedures like this. How can I update this table like trigger does instead of update trigger?
I tried below codes to get old and new end_dates but I can't.
Sample updated script in stored procedure:
ALTER PROCEDURE [dbo].[personnel_car_update]
(#PkId INT)
UPDATE tbl_personnel_cars
SET end_date = GETDATE()
WHERE pk_id = #PkId
EXEC update_operation_sp_instead_trigger #PkId
ALTER PROCEDURE [dbo].[update_operation_sp_instead_trigger]
(#PkId INT)
UPDATE pc
SET pc.owner_changed = 1
FROM tbl_personnel_cars pc
JOIN tbl_personnel_cars pc2 ON pc.pk_id = pc2.pk_id
WHERE pc.end_date <> pc2.end_date
And last question. Is it a correct choice to use stored procedure instead of trigger where the table is updated?
Firstly, I want to clarify a misunderstanding you appear to have about the UPDATE function in Triggers. UPDATE returns a boolean result based on if the column inside the function was assigned a value in the SET clause of the UPDATE statement. It does not check if that value changed. This is both documented feature, and is stated to be "by-design".
This means that if you had a TRIGGER with UPDATE(SomeColumn) the function would return TRUE for both of these statements, even though no data was changed:
UPDATE dbo.SomeTable
SET SomeColumn = SomeColumn;
UPDATE ST
SET SomeColumn = NULL
FROM dbo.SomeTable ST
WHERE SomeColumn IS NULL;
If, within a TRIGGER, you need to check if a value has changed you need to reference the inserted and deleted pseudo-tables. For non-NULLable columns equality (=) can be checked, however, for NULLable columns you'll also need to check if the column changed from/to NULL. In the latest version of the data engine (at time of writing) IS DISTINCT FROM makes this far easier.
Now onto the problem you are actually trying to solve. It looks like you are, in truth, overly complicated this. Firstly, you are setting the value to GETDATE so it is almost certainly impossible that the column will be set to be the same value it already set to; you have a 1/300 second window to do the same UPDATE twice, and if you add IO operations, connection timing, etc, that basically makes hitting that window twice impossible.
For what you want, just UPDATE both columns in your procedure's definition:
ALTER PROCEDURE [dbo].[personnel_car_update] #PkId int AS --This has a trailing comma, which is invalid syntax. The parathesis are also not needed; SP's aren't functions. You were also missing the AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.tbl_personnel_cars --Always schema qualify
SET end_date = GETDATE(),
owner_changed = 1
WHERE pk_id = #PkId;
END;
Larnu gave you a great answer about the stored procedure logic, so I want to answer your question about "Is it a correct choice to use stored procedure instead of trigger where the table is updated?"
The upsides of DML triggers are following in my opinion:
When you have a lot of places that manipulate a table, and there need to be some common logic performed together with this manipulation like audit / logging, trigger can solve it nicely because you don't have to repeat your code in a lot of places
Triggers can prevent "stupid" actions like: DELETEs / UPDATEs without WHERE by performing some specific validation etc. They can also make sure you are setting all mandatory fields (for example change date) when performing adhoc updates
They can simplify quick and dirty patches when you can concentrate your logic to one place instead of X number of procedures / compiled code.
Downside of triggers is performance in some cases, as well as some more specific problems like output clause not working on the triggered tables and more complicated maintenance.
It's seldom you can't solve these issues with other non-trigger solutions, so i'd say if your shop already uses triggers, fine, but if they don't, then there's seldom a really good reason to start either

Invoking procedure from a trigger to validate birthdate

I have created a trigger below (Trig 1)to fire before insert on employee table. Then this trigger will invoke the procedure (Proc 1) which will validate the birthdate being not earlier the the current date. if not proceed with the insert, but if date is earlier than current date, it will show a message like "invalid birthdate".
(Trig 1)
create or replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
declare
birth_date date;
employee_birthdate date;
begin
birth_date := employee_birthdate;
val_bday_proc birth_date;
end VALIDATE_BDAY_TRIG;
(Proc 1)
create or replace procedure val_bday_proc(
date_of_birth in date)
as
begin
if date_of_birth > current_date()
then raise_application_error(-20000, 'Employee birth date should not be earlier than the current date');
end;
When calling a stored procedure, you should pass variables between parentheses:
val_bday_proc(birth_date)
Also, you need to get the actual value that is to be inserted, because now employee_birthdate is just a variable, and will be null. You can use :new.fieldname to get the value of the field 'fieldname' of the new record. No need to declare variables for that at all, so your trigger could look like this, assuming the field is called employee_birthdate:
Create or Replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
begin
val_bday_proc(:new.employee_birthdate);
end VALIDATE_BDAY_TRIG;
The stored procedure seems to be okay, except it's missing the end if; to close the if-statement.
Some side notes:
You seem to be confusing earlier and later. The code in the proc is okay, but in the error message and in your question text you got it the other way around.
You could (maybe should?) also check this on update, otherwise you can insert an earlier date and then update it to some date in the future. You could make a separate trigger for this, or modify the current one to also trigger on update: (before insert or update).
It may help to have a naming convention for triggers that show their context (whether they are insert and/or update, row level or statement level). That helps you find the right one if you have multiple triggers.
It's a good idea to at least consider not putting this in a trigger at all. I learned the hard way that having a lot of business logic in triggers will eventually affect performance, is hard to debug, and hard to change. These kind of checks could be made in an application layer that stores the employee-data.

Execute stored procedure in a trigger

I do not know if its possible... if not give any idea to achieve this situation.
Let me explain what I want to do:
I want to fire trigger after insert to execute procedure then this procedure will read data from selected table name by user and store it into another table.
First I have an application that reads 2 values from user something like:
Read_From For_Month
And Read_From contains 3 values
(1) Read From Employees
(2) Read From Entity
(3) Read From Salaries
And For_Month the user select a date
Employees table:
Emp_ID EMP_NAME EMP_SHARE FOR_MONTH
---------------------------------------
121 Salim 25.8 01/06/2015
I want to fire trigger after click add button in my application.
So, this trigger will store entered values by user and pass it to procedure for execution, then the procedure will be execute based on these values to read from which table? And for which month?
If it's possible I need this trigger and procedure guys
I'm not sure I fully understand your needs, but here is what I think...
Here, I'm assuming that you have your client (Web) application, some middleware/server-side logic (say a SERVLET) that is approached by your application, and the DB behind the middleware.
First, you don't trigger things within the DB by clicking on a button of your Web application. What you do, is to invoke a stored procedure that performs some actions.
You can proceed in one of two ways:
The stored procedure you invoke when clicking on the button performs the insert and invokes the additional logic that needs to run using the inserted data
You create a trigger on the table into which the data needs to be inserted, where this trigger invokes the logic that needs to be executed using the inserted data. The stored procedure you invoke when clicking on the button will just insert the new data (and, due to the trigger, the additional logic will be executed).
Hope this is what you were looking for.

sql server trigger to update another database whenever a sproc is created

Is there a way to update another database with the newly created stored procedure whenever a stored procedure is created in the main database?
For example, i have two databases, DB1 and DB2.
When I create a stored procedure in DB1, i want that same procedure to created in DB2 automatically? Is there a trigger that can do this?
USE [DB1]
CREATE PROCEDURE [dbo].[TestSproc]
..something
AS
BEGIN
...something
END
I know a use [DB2] statement will do the job, but i want this to be done automatically. Any thought?
Thanks for the help!
This might be a bit evil, but in SQL Server you are able to create DDL triggers which fire when you create/alter/drop tables/procedures etc. The syntax to fire when a procedure is created is:
CREATE TRIGGER <proc-name>
ON DATABASE
FOR CREATE_PROCEDURE
AS
--Your code goes here
In a DDL trigger you get access to an object called EVENTDATA. So to get the text of the procedure you created:
SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
Now all you need to do is keep that value and execute it in your secondary database. So your query becomes something like this, though I leave the code to update the secondary database down to you as I don't know if it's on the same server, linked server etc.:
CREATE TRIGGER sproc_copy
ON DATABASE
FOR CREATE_PROCEDURE
AS
DECLARE #procedureDDL AS NVARCHAR(MAX) = EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
--Do something with #procedureDDL
As this is not tested, there's probably a few gotchas. For example, what happens if you create procedure with full name (CREATE PROC server.database.schema.proc)
No simple solution for this unless you want to execute the same statement twice, once on each target database,
One thing that comes to my mind is that you can Set up Replication and only publish Stored Procedures to your second database which will be the subscriber in this case.
Following is the window where you select which Objects you want to send over to your secondary databases.

Oracle triggers and stored procedures

I need to make for my webApp a trigger to execute a stored procedure on Oracle. But i'm very new to Oracle and I'm still getting the hang of it. I can make a simple Trigger with a sequence to auto-increment a value from a table, but that's it.
Is there any good tutorials and examples available on this specific subject? I tried searching here, but i have only found a very generic question: How can i learn Stored Procedure and Trigger?. But i can be more specific: I need this trigger to run a stored procedure that generates a new code for my user, adding data to this code. The procedure is done, i just don't know how to use it in a trigger, pass the parameters, and how to insert/update values from the oracle trigger itself.
Help will be much appreciated.
Assuming your function to generate the code is named f_generate_code() and your table is named foobar and the column that should be populated is name code you'd do it like this:
create or replace trigger trg_update_code
before insert or update on foobar
for each row
begin
:new.code := f_generate_code();
end;
/