I had a table employeeswipe_tbl in SQL Server 2008 with these columns:
create employeeswipe_tbl swipepk int (
swipepk int primary ,
empid int,
dateofswipe date ,
intime datetime,
outime datetime,
logduration time
)
When employee login in the intime, empid, dateofswipe is entered and when log out the outime is updated against swipepk
Now what I want is when I update outtime the logduration will be automatically calculated like
logduration = outtime - intime
I am thinking of a some ideas like a computed column or a trigger. Can anyone give a good option considering I am a beginner ?
A computed column is usually a better option than a trigger. Triggers can be disabled. A computed column is "always" correct:
create table employeeswipe_tbl (
swipepk int primary key,
empid int,
intime datetime,
outime datetime,
dateofswipe AS CONVERT(date,intime) ,
logduration AS DATEDIFF(second,intime,outime)
)
As indicated in my comment, the difference between two datetimes would be a time span, not another datetime. There's no time span type in SQL Server, so just keeping the difference in seconds is probably best - do any formatting of it into hours, minutes and seconds during display. This will make it easier if you need to, for instance, add together several rows worth of data.
Side note - I was considering making dateofswipe a computed column also - isn't it just the date part of intime?
Related
I am using SQL Server 2019.
I am using a system-versioned table like that:
CREATE TABLE Employee
(
EmployeeID int PRIMARY KEY NOT NULL,
FirstName varchar(100) NOT NULL,
LastName varchar(100) NOT NULL,
-- Some other columns
StartTime datetime2 (7) GENERATED ALWAYS AS ROW START NOT NULL,
EndTime datetime2(7) GENERATED ALWAYS AS ROW START NOT NULL,
PERIOD FOR SYSTEM_TIME (StartTime,EndTime)
)
WITH (SYSTEM_VERSIONING = ON(HISTORY_TABLE = dbo.EmployeeHistory));
The names of the table and the columns are changed, but this is how the table is created.
My question is pretty simple, but I can not find satisfying answer.
This table is available for the end users and one of the options is to provide DateTime SearchDate and I want to return all records in the Employee table which are made this Date.
However, even though the user may send not just Date but also Time the response should contain all records made the given Date in SearchDate and ignore the time.
Basically the queries which I found relate to system-versioned table are pretty simple:
SELECT *
FROM dbo.Employee
FOR SYSTEM_TIME BETWEEN #SearchDate AND ???
WHERE dbo.Employee.EmployeeID=2
After my research what I found is that I can take advantage of the system-versioned table and search after given DateTime or search in given DateTime range for which I found several different syntax which seems like at the end they provide the same result. Sadly, I wasn't able to find something built in which will search the entire date.
So my question is - is there way to take advantage of the fact that I am using system-versioned tabled and filter all records for a given Date no matter the Time component.
If not, I think that a decent workaround would be to use this clause FOR SYSTEM_TIME BETWEEN. As input I get DECLARE #SearchDate DATETIME2(7) so I would accept as an answer also a query which will the this #SearchDate and transform it in a way where I can extract the correct format of a DateTime which will indicate the very start of the #SearchDate date and the very end of the #SearchDate date so I can use those value in the BETWEEN syntax?
You can just use DATEADD and CAST to get the start and end of the day
DECLARE #startDate datetime2(7) = CAST(#SearchDate AS date);
DECLARE #endDate datetime2(7) = DATEADD(day, 1, #startDate);
SELECT *
FROM dbo.Employee
FOR SYSTEM_TIME BETWEEN #startDate AND #endDate
WHERE dbo.Employee.EmployeeID = 2;
Note that for BETWEEN, the start point is exclusive and the end point is inclusive.
I am building a database application with C# in Visual Studio 2013. The application is meant to email a customer 90 days after the date of their visit so, when they come in, their info is taken and today's date is stored with their other information.
I have a table called Customer ready to store customer information but instead of having the user type the date for each customer and risk them screwing up the format, I would like the default value for the column named DateOfVisit to be today's date.
I am looking for what to type into the default column. Something along the lines of getDate() that will give me today's date in a format that I can easily check against another future date and see if 90 days have past or not.
EXTRA: From the picture, you may notice I have the emailFlag's data type set to bit because I thought that would be the closest thing to a boolean. The purpose of emailFlag is that before a customer is sent an email, that flag will be checked and if it's false the email will go through and the flag will be set to true, so as to avoid spamming the customer emails in case the program messes up. Is this a good idea? Do you have any suggestions as to how I could do it better?
tl;dr
I need a method that will give me today's date to store in a database and that I can compare with other dates.
Try this:
In case you already have the table created
Alter Table dbo.customer Drop Column DateOfVisit;
Lets alter the table and add a field with the deafult value date
Alter Table dbo.customer ADD DateOfVisit DATETIME NOT NULL DEFAULT (GETDATE());
I have month in an integer variable int month =DateTime.Now.Month; and I have Two dates in database they are '11/01/2014'and '11/30/2014' . Now I want to bring least and grater days in a string. how can I achieve it.(in database I have Fromdate('11/01/2014') and Todate('11/30/2014')fields)? I am new in this field.
There are Min and Max functions you can use to find this. The best way to use these is to ensure that you are first storing the date as a date or datetime value (or similar), as casting from one type to another can be an expensive operation.
Sample:
Select Min( MyDateColumn) as "MinDate", Max(MyDateColumn) as "MaxDate"
From MyTable;
If they are not stored as a form of date value, you will have to cast the value to a date. If it is stored as a varchar or char, for example, you will need to do this. If you don't, the min and max will be calculated based on the ascii values of characters, not on the actual dates.
Sample (avoid, if possible):
Select Min( CAST(MyDateColumn as date) ) as "MinDate",
Max( CAST(MyDateColumn as date) ) as "MaxDate"
From MyTable;
I need to sort by date but the date is stored as text in the database. I am using Linq to entities to perform queries.
The way the database is designed it is not feasible to change the column to a date column because many different data types are in that column. There is a descriminator column named type so I will know what type a particular row is.
You can add a computed column to the table that will convert those strings to dates when your discriminator has a specific value (here I've just used 'date').
ALTER TABLE Foo
ADD trueDate AS
CASE
WHEN type = 'date' THEN CONVERT(date, 'mixedColumn', 101)
ELSE NULL
END
PERSISTED
If you have time information, then date should be datetime in the CONVERT() function.
Also, the 101 is a style code indicating an expected format of MM/dd/yyyy. If you have something different, refer to this: http://msdn.microsoft.com/en-us/library/ms187928.aspx, but keep in mind that if you use a style below 100 your expression will be considered non-deterministic and you cannot make your computed column PERSISTED, so the conversions will be done on the fly with each query (you don't want that).
The computed column will update itself when the row values change; otherwise the values are persisted and queryable just like in any other column. No triggers required.
If all your rows containing dates use the same date format you could just order by their string value. But since the most common (i.e english) date format does NOT start with the year, that could prove problematic.
Option A.: Sort in memory.
var records = db.YourTable.Where(o=>o.Discriminator =="date").AsEnumerable()
.Select(o=>new {Entity= o, Date=DateTime.Parse(o.YourColumn)})
.OrderBy(o.Date).Select(o=>o.Entity);
Do NOT do this if you have a lot of rows, or if you have to, at least have the decency to cache the ordered result...
Option B.: Database magic
Add an extra column to your DB, make THAT Date (nullable), and update that if the discriminator is date. You can either update it in a (DML) Trigger or from C#...
OR if the conversion is simple you could build a view out of it...
I am trying to insert a datetime stamp from an asp.net application into a db, but i keep recieving an error ::
The column "W_Date" cannot be modified
because it is either a computed column
or is the result of a UNION operator.
Can someone shed some light on this. Also, I automate the datetime in my asp in a label, then pull the text for the sql insert with the following code.
lblDate.Text = DateTime.Now.ToString();
Is this correct?
Below is my stored Proc code:
#date date
AS
BEGIN
INSERT INTO tbl_Wiki(W_Title, C_ID, W_Date)
VALUES (#title, #c_ID, GETDATE())
END
It doesn't sound like there's anything wrong with your ASP.NET code, assuming the W_Title is the correct column name. Do you have enough control over the schema to see if W_Title is a computed column or not?
Also, it looks like you're passing in "date" as a parameter to your proc, but you're not using it in the INSERT statement. If W_Date is a computed column to always be the current date, you should remove the W_Date paramter in your insert statement.
Check the definition of the column W_Date in table tbl_Wiki. It's probably a computed column, which means you can't modify it.
You could use this query to check if a column is computed:
select is_computed
from sys.columns
where object_id = object_id('tbl_Wiki')
and name = 'W_Date'
Example of a computed column:
create table Sample (a int, b int, c as sqrt(a*a+b+b))
Here, c is computed every time the row is retrieved. You can't overrule the calculation by specifying a value during an insert or update.