How do I automate the running of a SQL query? - asp.net

What should i research in order to accomplish this task?
I am using MS-SQL & VB.Net
I have a SQL table that stores startdate and enddate. I want to run a query on that table every 10 minutes in order to check if the enddate is greater than today and if it is I would like to add a 1 to another column if it is not I would like to add a 0.
How can I achieve this?

Your question seems like you're asking for the wrong thing.
It sounds like you are looking for a trigger to fire off and update a calculated field. So it sounds like you want to setup a database trigger on the table and have that trigger fire on insert or update
USE [<database_name>]
GO
/****** Object: Trigger [dbo].[tr_<tablename>_endDateCheck] Script Date: 03/16/2011 12:42:24 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[tr_<tablename>_endDateCheck]
ON [dbo].[<tablename>]
AFTER INSERT,UPDATE
AS
BEGIN
UPDATE [<tablename>] SET isEnded = CASE WHEN (SELECT endDate FROM inserted WHERE id = inserted.id).endDate > GetDate() THEN 1 ELSE 0 END WHERE id IN (SELECT ID FROM inserted)
END
GO
Or something very similar to this anyway
You then put a scheduled job that will run at 0001 hour and update all the records which had endDate = yesterday's date
UPDATE [<tablename>] SET isEnded = 1 WHERE isEnded = 0 AND endDate BETWEEN DATEADD(DAY, -1, GETDATE()) AND GETDATE()
edit: or is endDate actually time specific as well?
Perhaps in this case you should be using a view to select your data instead with a view definition of:
SELECT *, CASE WHEN endDate > GetDate() THEN 1 ELSE 0 END AS HasEnded
FROM [<TableName>]
Edit2: fixed issue with the scheduled job which was not correct for endDate values that include a time value

Create a SQL Server job to run your update query.
UPDATE YourTable
SET AnotherColumn = AnotherColumn + 1
WHERE enddate > DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0) /* Today's date at midnight */

You can write a SQL Job, or if you want write a service to run against the database, if you are more comfortable in code or the actions require more extensive business rules.

Related

PL/SQL Trigger exercise

I have this question that I can see what it's asking but just can't wrap my head around how to write it specifically:
When a new tuple is inserted into the sales order detail, your trigger should insert a corresponding raw material tuple in the Inventory Report table for the Report date (i.e., beginning inventory level, consumption quantity, same-day order quantity, next-day order quantity)
Assumptions I gathered from the notes:
itemID = itemID from RAWMATERIALS table
reportDate = dueDate from SALESORDERS table
begInv = inventoryLevels from RAWMATERIALS table
consumpQty = itemID from FINISHEDGOODS * rmQuantity (raw material required to make each finished good) from FINISHED GOODS
orderNextDay = If consumpQty <= begInv then orderNextDay = consumpQty
orderSameDay = 0
orderSameDay = If consumpQty > begInv then orderNextDay = begInv
orderSameDay = consumpQty - begInv
I thought the trigger might go something like:
CREATE OR REPLACE TRIGGER inv_report
BEFORE INSERT
ON SALESORDERDETAIL
FOR EACH ROW
DECLARE
item_id RAWMATERIALS.ITEMID%TYPE
reportDate SALESORDERS.DUEDATE%TYPE
begInv RAWMATERIALS.INVENTORYLEVEL%TYPE
And then I understand we would probably need to INSERT into INVENTORYREPORT table (which currently has no data in it) and maybe do an IF ELSEIF statement to satisfy the orderNextDay and orderSameDay columns but i'm still not familiar enough with PL/SQL to know exactly how to tackle this.
Can anyone help me out with this? Thanks!
I'll try to find some time to write up some code for you on this, but my first recommendation is to NOT do this in a trigger. Instead, create a procedure "insert_so_detail" that inserts into the the SALESORDERDETAIL and then does the related insert into INVENTORYREPORT.
That procedure is then always called to insert into the S-O-D table. Executing DML inside triggers is a tricky thing to do because the database might decide it needs to restart the DML and then possibly do another insert into the I-R table. Check out this AskTOM thread for more details.
You are always better off putting your DML into PL/SQL package APIs, then only allow DML on the table through the API (grant execute on the package, do NOT grant insert or update or delete on the table directly to a user).

SQL trigger to check customer age not working

I am trying to add a constraint to cust_birthdate, make sure the customer is more than 18 years old.
Here is my create table statement
create table customer(
cust_id char(5) NOT NULL,
cust_name varchar(30),
cust_birthdate date,
primary key(cust_id)
);
I found out cannot use SYSDATE in constraint, but I found a trigger online that fit my situation.
Here is the trigger I modified:
CREATE OR REPLACE TRIGGER trgCustomer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
IF(ADD_MONTHS(:new.cust_birthdate, 18 * 12) < sysdate ) THEN
RAISE_APPLICATION_ERROR(-20001, 'Customer must be at least 18 years old.' );
END IF;
END;
/
However, the trigger will not work when I insert something like this:
insert into customer values('C0001', 'Chek Wei', TO_DATE('20-OCT-2016', 'dd-MON-yyyy'));
The 'Chek Wei' customer is less than 18 years old, but no error message is shown.
I do not yet learn trigger but I since I cannot use SYSDATE on constraint, I have no choice.
What's wrong with my trigger?
I am using Oracle Database Express Edition 11g Release 2
Any help is appreciated.
Isn't that logic reversed? you want only when you add 18 years to that date is
GREATER than sysdate to fire the error......
There you go.... :)

SQL in Power Query using ODBC

I have a Table with following Columns:
Account_No, Start_Date, End_Date
I downloaded this table into power query using SQL Select command through ODBC.
Now i want to get sum and count of transactions of all accounts given in the above table from Start_Date to End_Date from another Table. e.g. Transaction_Table. What should i do to get my desired results.
Regards
KAM
You probably don't need Power Query at all at this point.
Assuming your DB server is MS SQL Server 2008 or higher,
WITH t1([Account_No], StartDate, EndDate) As
(
SELECT [Account_No], StartDate = MIN([Start_Date]), EndDate = MAX([End_Date])
FROM Table1
GROUP BY Account_No
)
SELECT
[Account_No]
, Amount = SUM([Field_Transaction_Total])
, [Transaction_Count] = COUNT([Field_Transaction_ID])
FROM [Transaction_Table] t2
INNER JOIN t1 ON t2.[Account_No] = t1.Account_No
AND t2.[Field_Transaction_Date] BETWEEN t1.StartDate AND t1.EndDate
You can also use a copy of a query inside WITH block to get this table with accounts and dates to Excel, if you need it.
If you use another SQL Server, just refactor this code, I hope you've got the idea.
You could use a GROUP BY statement in the SQL you wrote, or you could filter the table based on the Start_Date to the End_Date and then right-click on the column you want to count and choose Group By.
I would start a new Query based on your Transaction_Table. Then I would add a Merge step, joining to your 1st Query on Account_No. Then I would Expand the Start_Date and End_Date from the generated NewColumn.
Next I would Add a Custom Column, and write a formula like this:
= [Transaction_Date] >= [Start_Date] and [Transaction_Date] <= [End_Date]
The resulting column will show TRUE or FALSE. Filter for TRUE.
Finally I would add a Group By step to Sum and Count as required.
I hope I've understood your requirement correctly - it wasn't really clear from your question.

Insert multiple rows into SQL Server based on start and end dates

I need to insert several rows into a SQL Server database based on Start Date and End Date textboxes.
E.G. tbStartDate.Text = "25/12/2012" and tbEndDate.Text = "29/12/2012" therefore I need to insert individual rows for the following dates:
25/12/2012
26/12/2012
27/12/2012
28/12/2012
29/12/2012
Please can you help me with the necessary T-SQL to achieve this?
As always there are a few ways. Here are some of them:
You can write code in your app that loops through the days and inserts a single record per day. (generally the worst design)
You can call some SQL script to do it all in the database.
You can wrap up your SQL script in a stored procedure and pass in the start and end date and get the stored procedure to do it for you.
You can cross join to a pre existing tally table and use it to generate your records.
If you can provide
-the version of SQL Server that you're using
-what the table looks like
-whether you're using C# or VB
then we can help further as it can be difficult to pass dates into databases. It can be particularly difficult if you do not validate them.
Anyway here is option 3 for you.
CREATE PROC dbo.t_test
#StartDate DATETIME,
#EndDate DATETIME
AS
WHILE #StartDate <= #EndDate
BEGIN
INSERT INTO YourTable(YourDateField) VALUES (#StartDate)
SET #StartDate = DATEADD(d,1,#StartDate)
END
Then you need to call this stored procedure (called dbo.t_test) from ASP.Net and pass in your two date parametes as dates.
Declare #Startdate datetime
Select #Startdate='20121025'
While #Startdate<='20121029'
begin
if not exists(select * from dummy where DATE=#Startdate)
insert into dummy (date) values (#Startdate)
set #Startdate=#Startdate + 1
end;

Column 'AuctionStatus' cannot be used in an IF UPDATE clause because it is a computed column

I am developing an Auction site in asp.net3.5 and sql server 2008R2, My Database has an Auction Table that has a calculated column "AuctionStatus" -
(case when [EndDateTime] < getdate() then '0' else '1' end)
that gives auction status Active or inactive based on End Date.
Now I want to call a stored procedure that sends email notifications to buyers and sellers as soon as AuctionStatus becomes '0'. For that i tried to create a after update trigger that could call the email notification sp, but i am not able to do so.
I am getting the following error message :-
Msg 2114, Level 16, State 1, Procedure trgAuctionEmailNotification,
Line 6 Column 'AuctionStatus' cannot be used in an IF UPDATE clause
because it is a computed column.
The trigger is:
CREATE TRIGGER trgAuctionEmailNotification ON SE_Auctions
AFTER UPDATE
AS
BEGIN
IF (UPDATE (AuctionStatus))
BEGIN
IF EXISTS (SELECT * FROM inserted WHERE currentbidderid > 0
AND AuctionStatus='0' )
BEGIN
DECLARE #ID int
SELECT #ID = AuctionID from inserted
EXEC spSelectSE_AuctionsByAuctionID #ID
END
END
END
You could just replace AuctionStatus with the corresponding expression :
IF EXISTS (SELECT * FROM inserted WHERE currentbidderid > 0 AND [EndDateTime] < getdate() )
But, the point is I don't see how your trigger will be "triggered" as [AuctionStatus] is never "updated". Its Value is just calculated whenever you need it.
You could go for a sql job that runs every x minutes and send a notification for each auction which ended during the last x minutes.
You need to add a real column containing a flag to indicate whether the notifications have been sent, and then implement a polling technique to scan the table for rows where the status is inactive and notifications haven't been sent.
The computed column doesn't really transition from one state to another, so it's not like an UPDATE has occurred. Even if SQL Server did implement this, it would be hideously expensive, since it would have to query the entire table for transitioning rows every 3ms. (or even more frequently if you're using datetime2 with a higher precision)
Whereas you can pick a suitable polling interval yourself. This could be an SQL agent job, or in some service code somewhere, whatever best fits the rest of your architecture.

Resources