I have create a table with
create table tblConsultationHour
(
consultationID int primary key identity,
cday varchar(50),
cstartTime datetime,
cendTime datetime
)
I want to insert value of the day name into cday, and i should know the day name from the cstarttime of date part. what i know on how to get the day name with this code
SELECT DATENAME(dw,'2011-10-26 12:35:29.123')
may i know how can i insert this on the fly ?
or is that possible to insert in this way ?
insert into tblConsultationHour values
(SELECT DATENAME(dw,'2011-10-26 12:35:29.123'),'2011-10-26 12:35', '2011-10-26 14:35')
You were close:
INSERT INTO tblConsultationHour
SELECT DATENAME(dw,'2011-10-26 12:35:29.123'),'2011-10-26 12:35', '2011-10-26 14:35'
Also check out this question for other examples: SQL INSERT from SELECT
Another approach to consider is a computed column:
create table tblConsultationHour
(
consultationID int primary key identity,
cday as DateName(dw,cStarttime),
cstartTime datetime,
cendTime datetime
)
In your example, cDay is a redundant column. As written, if someone changes the cStarttime value, they must also remember to update the cDay field. While it might not occur or be an issue, it is something to keep in mind...
Related
I have a table where records have a (begin, end) time window of existence (for things like employement duration, birth and death, rent duration, ...)
begin IS NULL or end IS NULL if there is no bound.
CREATE TABLE mytable(
id int primary key,
value int, --UNIQUE at any point in time
begin datetime NULL,
end datetime NULL
);
I want column value to be unique at any point in time.
INSERT INTO mytable VALUES(1, 1, '2021-07-23', '2021-07-24'),(2, 1, '2021-07-25', NULL);
Is OK
Whereas
INSERT INTO mytable VALUES(1, 1, '2021-07-23', '2021-07-30'),(2, 1, '2021-07-25', NULL);
Is not OK, because both records have value=1 and overlapping time windows.
Is there a way to enforce such a constraint in SQL ?
You can't do this on the table, no, as there's nothing to make UNIQUE on.
What you could do, however, is use a VIEW to enforce it.
Firstly, let's create your table. I assume the columns datetime, should actually be begin and end; I recommend against these names as they are reserved keywords. As such I am calling them DateBegin and DateEnd. I am also assuming that they are date only (no time portion) values and so define them as a date not a datetime:
CREATE TABLE dbo.mytable(ID int primary key,
Value int,
[BeginDate] date NULL,
[EndEnd] date NULL);
And we'll INSERT your first 2 rows, as they are "ok":
INSERT INTO dbo.mytable (ID, Value, BeginDate, EndDate)
VALUES(1, 1, '20210723', '20210724'),
(2, 1, '20210725', NULL);
Now we need to make a VIEW, but we need one row per date. As such you'll want to create a Calendar Table. I'm not going to cover how to create one here, but there are literally 100's of articles, such as there on SQL Server Central: Bones of SQL - The Calendar Table, Calendar Tables in T-SQL.
Once you have your Calendar table, you can create the VIEW below, which JOINs the data in your table to the calendar table. We're going to make it so that the VIEW just returns the columns value and the date. WE're also going to schemabind it; this means we'll be able to add an UNIQUE INDEX to it:
CREATE VIEW dbo.MyView
WITH SCHEMABINDING
AS
SELECT MT.[Value],
CT.CalendarDate
FROM dbo.MyTable MT
JOIN dbo.CalendarTable CT ON MT.BeginDate <= CT.CalendarDate --I assume, despite your schema, MT.BeginDate can't be NULL
AND (MT.EndDate >= CT.CalendarDate OR MT.EndDate IS NULL);
Now we have a VIEW that has a row for each date, and for each value. This means we can now create our UNIQUE INDEX:
CREATE UNIQUE CLUSTERED INDEX MyIndex ON dbo.MyView ([Value], CalendarDate);
Now if we try to INSERT a row that is on the same date and value, we'll get an error:
INSERT INTO dbo.MyTable (ID, Value, BeginDate, EndDate)
VALUES(3, 1, '20210720', '20210723');
Cannot insert duplicate key row in object 'dbo.MyView' with unique index 'MyIndex'. The duplicate key value is (1, 2021-07-23).
I want to create a table with computed column for its custom ID column. The format which I want is BID(The Year)-0000 for example the one like this:
BID2017-0001
I tried the below t-sql code but I get the non-deterministic error. How can I solve this problem?
CREATE TABLE Books
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookID AS 'BID'+CAST(YEAR(GETDATE()) as VARCHAR(4))+ RIGHT ('0000' + CAST(ID AS VARCHAR(4)), 4) PERSISTED UNIQUE,
ISBN VARCHAR(32),
BookName NVARCHAR(50),
AuthorName NVARCHAR(50),
BLanguage VARCHAR(50),
StaId int,
StuId int,
CatNo int);
I tried this article too but couldn't solve the issue.
non-deterministic
UPDATE
Furthermore, I need the series of '0000' to be reset back to '0000' when the new year starts. For example, The last ID in 2017 is 'BID2017-0932' when the year is changed to 2018 I would like zero series in the ID to be reset to '0000' for example 'BID2018-0001' how can I achieve this ??
Simplest solution
I would add a CreateDate column thus:
ALTER TABLE dbo.Books
ADD CreateDate DATETIME NOT NULL
CONSTRAINT DF_Books_CreateDate
DEFAULT(GETDATE())
GO
then I would add computed column thus:
ALTER TABLE dbo.Books
ADD BookID AS ('BID' + LTRIM(YEAR(CreateDate)) + '-' + RIGHT('0000' + LTRIM(ID), 4)) /*PERSISTED*/
GO
you have getdate() in your code which makes the column non deterministic.Removing that will help ..
If you want to know why getdate() is nondeterministic.check here:Is GetDate() deterministic..
Excerpt from answer
deterministic means that the function returns the same value given the same inputs. In this case you have no inputs, but you get different values all the time! The system clock is not an input, it is external state that the function relies upon.
I need to add a constraint to one table in my database. The table name is Experience. And there is a column named ToDate. Every time the select statement executes like following.
select ToDate from Experience
It should return current date.
So every time select statement executes, the ToDate column get updated with current date.
I know I can do this with some type of sql trigger but is there a way to do it by sql constraint.
like
alter table add constraint...
Any help will be appreciated.
Thanks
You can use a computed column. That's specified like colname as <expression>:
create table t1(id int, dt as getdate());
insert t1 values (1);
select * from t1;
To add contraint ...
create table tbl (id int identity, dt datetime, colval varchar(10))
ALTER TABLE dbo.tbl
ADD CONSTRAINT col_dt_def
DEFAULT GETDATE() FOR dt;
Example of inserting to the table ..
insert into dbo.tbl(colval)
select 'somevalue'
select * from dbo.tbl
The result will be ..
id dt colval
1 2014-08-19 13:31:57.577 somevalue
You cannot use a constraint, because a constraint is basically a rule on what can go in the table, how the table can relate to others, etc. It has no bearing on the data in the table once it goes into the table. Now if I am understanding you correctly, you want to update the ToDate column whenever you select that column. Now you can't use a trigger either as mentioned here and here. They suggest a stored procedure where you would use an update followed by an insert. This is probably my preferred SQL method to go with if you have to use it repeated, which you seem to have to do. Though Andomar's answer is probably better.
Try this link code make help full
http://www.sqlatoms.com/queries/how-to-use-the-getdate-function-in-sql-server-3/
CREATE TABLE ProductOrders
(
OrderId int NOT NULL PRIMARY KEY IDENTITY,
ProductName nvarchar(50) NOT NULL,
OrderDate datetime NOT NULL DEFAULT GETDATE()
)
I'm having trouble creating a trigger for my database.
I Have two tables, lets call them A and AHistory.
A has an ID and a value.
I want AHistory to keep track of the value and date for a set time.
AHistory Has an Auto Incremented ID, the value and a timestamp.
this is as far as I have gotten:
CREATE TRIGGER Atrigger
ON A
AFTER INSERT
AS
BEGIN
INSERT INTO AHistory
SELECT value FROM INSERTED
END
GO
Assuming that your db schema looks like
CREATE TABLE a
(id int identity primary key,
value varchar(32));
CREATE TABLE ahistory
(id int identity primary key,
aid int, value varchar(32),
eventdate datetime);
Your trigger might look like
CREATE TRIGGER atrigger ON A
AFTER INSERT AS
INSERT INTO ahistory (aid, value, eventdate)
SELECT id, value, GETDATE() FROM INSERTED;
Here is SQLFddle demo
I have a primary key set up to auto increment.
I am doing multiple queries and I need to retrieve that primary key value to use as a foreign key in another table (IsIdentity = TRUE).
Is there any elegant way to get back the primary key value when I do an insert query? Right now I am requerying and getting the highest value in that column which seems really hacky.
Any suggestions?
If you are using SQL Server 2005 or later, you can use the OUTPUT clause.
create table T(
pk int identity primary key,
dat varchar(20)
);
go
insert into T
output inserted.pk
values ('new item');
go
drop table T;
The output can be directed to a table as well as to the client. For example:
create table T(
pk int identity primary key,
dat varchar(20)
);
create table U(
i int identity(1001,1) primary key,
T_pk int not null,
d datetime
);
go
insert into T
output inserted.pk, getdate()
into U(T_pk,d)
values ('new item'), ('newer item');
go
select * from T;
select * from U;
go
drop table T, U;
Beginning with SQL Server 2008, you can use "composable DML" for more possibilities.
insert into YourTable values (...)
get the new PK with scope_identity()
select scope_identity()
INSERT INTO YourTable (1, 2, etc.)
OUTPUT inserted.yourIDcolumn
VALUES (value1, value2, value...)
Note: This is for MS SQL 2005 and greater
SCOPE_IDENTITY() is probably what you want. It returns the ID of the last record inserted by the same code context in which it executes.
IDENT_CURRENT('tablename') is subject to concurrency issues. That is, there's no guarantee that another record won't be inserted between the INSERT and the call to IDENT_CURRENT.
I must confess, I'm not sure to what source of amazement the VillageIdiot's outburst refers, but I myself am quite astonished that this question does not appear to be a duplicate at all.
holy crap!!!
just call SCOPE_IDENTITY() function:
insert into your_talble(col1,col2) values('blah','more blah')
select scope_identity()
because selecting highest value will return error if any other statement make an insert. the function scope_identity() returns the identity created in current context (that is by your statement)
You should use scope_identity(). And I recommend to wrap insert statement and scope_identity() into transaction.