execute constraint on update sql - sql

I have a constraint that return datetime for a column (date).
On insert work it! Now I would like update column date with new value of getdate() when an update statement execute. Any idea?
My constraint:
ALTER TABLE [tablename] ADD CONSTRAINT [constraintName]
DEFAULT (getdate()) FOR [column]
MY DBMS is Microsoft SQL Server 2012

You can do it using a trigger like this:
CREATE TRIGGER updTableDate
ON [Table]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE [Table] SET modified = GETDATE() WHERE [primary_key] IN (SELECT [primary_key] FROM INSERTED)
END
Or better:
CREATE TRIGGER updTableDate
ON [Table]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE [Table] t SET modified = GetDate() FROM INSERTED AS i WHERE t.id = i.id
END

Related

Modify SQL Trigger to work with BULK INSERT

I have a SQL Trigger that doesn't fire because the records in the table are inserted through a BULK INSERT. I do not have access to the code that inserts the records so I need to modify this trigger to handle the BULK INSERT. This is the trigger:
USE [testdata]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[Trigger_test] ON [dbo].[test]
AFTER INSERT , UPDATE
AS
BEGIN
DECLARE #BatchId int, #Ethanol decimal(18,6), #Glucose decimal(18,6), #SampleAge varchar(50);
SELECT #BatchId = CONVERT(int,bd.[BatchId]),
#Ethanol = CONVERT(decimal(18,2),[Ethanol]),
#Glucose= CONVERT(decimal(18,2),[Glucose]),
#SampleAge = bd.SampleCode
from INSERTED bd
update [dbo].[DeSchedule]
SET
[Ethanol] = #Ethanol,
[Glucose] = #Glucose,
[SampleCompleted] = 1
WHERE [BatchID] = #BatchId AND [SampleAge] = #SampleAge
END
Can anyone help me in modifying this trigger to handle the BULK INSERT.
Unless you can modify the BULK INSERT statement you are stuck. By default triggers do NOT run during a bulk insert. You must explicitly turn them on in the command with the FIRE_TRIGGER option.
Only need to edit BULK INSERT File below:
BULK INSERT AdventureWorks2012.Sales.SalesOrderDetail
FROM 'f:\orders\lineitem.tbl'
WITH
(
FIELDTERMINATOR =' |'
, ROWTERMINATOR = ':\n'
, FIRE_TRIGGERS
);
USE [testdata]
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER TRIGGER [dbo].[Trigger_test] ON [dbo].[test]
AFTER INSERT , UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #BatchId int, #Ethanol decimal(18,6), #Glucose decimal(18,6), #SampleAge varchar(50);
Declare CurI cursor for
SELECT [BatchId],[Ethanol] ,[Glucose], SampleCode from INSERTED
Open CurI
fetch next from CurI into #BatchId,#Ethanol,#Glucose, #SampleAge
while ##fetch_status=0
Begin
update [dbo].[DeSchedule]
SET
[Ethanol] = #Ethanol,
[Glucose] = #Glucose,
[SampleCompleted] = 1
WHERE [BatchID] = #BatchId AND [SampleAge] = #SampleAge
Fetch next from CurI into #BatchId,#Ethanol,#Glucose, #SampleAge
End
Close CurI
Deallocate CurI
END
the problem is it selected only the last row of the inserted table ,i think if you change the query like this it would work
update [dbo].[DeSchedule]
SET
[Ethanol] =(select CONVERT(int,bd.[Ethanol]) from inserted bd),
[Glucose] = (select CONVERT(decimal(18,2),[Glucose]) from inserted bd),
[SampleCompleted] = 1
WHERE [BatchID] = (select CONVERT(int,bd.[BatchId]) from inserted bd) AND [SampleAge] = (select bd.SampleCode from inserted bd)

SQL - Continue running all SQL statements even after error

I have some queries like this
Alter Table Table1 ALTER COLUMN T1 varchar(MAX);
Alter Table Table1 ALTER COLUMN T2 varchar(MAX);
Alter Table Table1 ALTER COLUMN T3 varchar(MAX);
--Table2 does not have a column "R1" and is likely to give error
Alter Table Table2 ALTER COLUMN R1 varchar(MAX);
Alter Table Table2 ALTER COLUMN T1 varchar(MAX);
Alter Table Table2 ALTER COLUMN T2 varchar(MAX);
Alter Table Table2 ALTER COLUMN T3 varchar(MAX);
Possible Error
Now in the 4th statement it is likely that a message would pop because there is no field in Table2 named R1.
Need
I need a way so that all the statement gets executed even after receiving the error.
My Approach
I tried to execute these statements individually to receive error message for every line but it takes too much time as it makes 7 times connection to a server which is connected to the PC by internet . So, i used all those query together to get records in one connection but it breaks the command on 4th line as the statement is invalid.
Any suggestion or piece of code is appreciated
You should use 'GO' between instructions in order to contine the execution no matter on the errors:
Alter Table Table1 ALTER COLUMN T1 varchar(MAX);
GO
Alter Table Table1 ALTER COLUMN T2 varchar(MAX);
GO
Alter Table Table1 ALTER COLUMN T3 varchar(MAX);
GO
Alter Table Table2 ALTER COLUMN R1 varchar(MAX);
GO
Alter Table Table2 ALTER COLUMN T1 varchar(MAX);
GO
Alter Table Table2 ALTER COLUMN T2 varchar(MAX);
GO
Alter Table Table2 ALTER COLUMN T3 varchar(MAX);
GO
This will give you all messages and will execute all the sentences one after each other. Those are my logs on a similar situation. As you will see, various errors are notified, and not only one:
NOTE: The catch behavior depends on the severity of the error, this
link from the MSDOC explains how try_catch works
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-2017
Hope it helps :)
Use a try-catch block:
Alter Table Table1 ALTER COLUMN T1 varchar(MAX);
Alter Table Table1 ALTER COLUMN T2 varchar(MAX);
Alter Table Table1 ALTER COLUMN T3 varchar(MAX);
BEGIN TRY
Alter Table Table2 ALTER COLUMN R1 varchar(MAX);
END TRY
BEGIN CATCH
print 'error altering column R1 of Table2';
END CATCH;
Alter Table Table2 ALTER COLUMN T1 varchar(MAX);
Alter Table Table2 ALTER COLUMN T2 varchar(MAX);
Alter Table Table2 ALTER COLUMN T3 varchar(MAX);
If Table2 does not have column R1 then the statement 'Alter Table Table2 ALTER COLUMN R1 varchar(MAX);' will not be a valid sql statement so the statement will not try to run so the catch will not happen. If instead you execute the statement it will try to run and the catch will work.
Alter Table Table1 ALTER COLUMN T1 varchar(MAX);
Alter Table Table1 ALTER COLUMN T2 varchar(MAX);
Alter Table Table1 ALTER COLUMN T3 varchar(MAX);
BEGIN TRY
execute ('Alter Table Table2 ALTER COLUMN R1 varchar(MAX);')
END TRY
BEGIN CATCH
print 'error altering column R1 of Table2';
END CATCH;
Alter Table Table2 ALTER COLUMN T1 varchar(MAX);
Alter Table Table2 ALTER COLUMN T2 varchar(MAX);
Alter Table Table2 ALTER COLUMN T3 varchar(MAX);
I have noticed that we get the desired behavior if the commands are run from inside an open session.
mysql -u root -p myDB < commands.sql >> stops on the first error
mysql -u root -p myDB
(after login)
source commands.sql
^^^ continues even after errors occur

SQL: multiple statements within a BEGIN and END

I'm trying to add a new column to an existing table which will be populated by a unique Guid value. I'm trying the following code:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
UPDATE dbo.Product
SET Product_Guid=NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
END
This won't work becasue the second statement doesn't recognise the new column name. I can't put GO or ; at the end of each statement though, presumably because I'm in the middle of the BEGIN/END block.
What's the best way of solving this dilemma?
The statement doing the update must be compiled after the column is added.
The way this is usually done is wrapping the statements in an EXEC:
EXEC(' UPDATE dbo.Product
SET Product_Guid = NEWID()
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
')
It seems like you want to set the default value and have the column be not null. You'll get the same effect if you just set the default value to NEWID()
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL DEFAULT NEWID()
END
If you need to remove the constraint after, you can create the DEFAULT constraint after you define the column in the alter statement and then drop the named constraint right after. If you don't name the constraint you'll have to get the name from sys.objects and then do dynamic sql to remove it.
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NOT NULL,
CONSTRAINT Default_Product_GUID DEFAULT NEWID() FOR Product_GUID;
ALTER TABLE dbo.Product DROP CONSTRAINT Default_Product_GUID
END
You could just update the table afterwards and then alter it in another code block, a little something like this:
IF NOT EXISTS(select * from sys.columns
where Name = N'Product_GUID' and Object_ID = Object_ID(N'dbo.Product'))
BEGIN
PRINT 'Creating new GUID column in dbo.Product table'
ALTER TABLE dbo.Product
ADD Product_GUID uniqueidentifier NULL
END
GO
UPDATE dbo.Product
SET Product_Guid=NEWID()
Where Product_Guid is null
if ##ROWCOUNT <> 0
Begin
ALTER TABLE dbo.Product
ALTER COLUMN Product_Guid uniqueidentifier NOT NULL
End

Condition in a stored procedure

i have a stored procedure that does 2 updates, but i only want to do the first update if the parameter #active is equals to 'Y'.
alter procedure sp_updateThis
#something varchar(5),
#active char(1)
as begin
-- check to see if active and do the update
update myTable set this=#something
-- run this one regardless
update yourTable set that=#something
Try changing that last line with this:
if (#active = 'Y')
begin
update yourTable set that=#something
end
alter procedure sp_updateThis
#something varchar(5),
#active char(1)
as begin
-- check to see if active and do the update
if(#active = 'Y')
Begin
update myTable set this=#something
End
-- run this one regardless
update yourTable set that=#something
If you're really trying to update every row in the table:
update myTable set this=#something where #active = 'Y';
Otherwise you probably want additional clauses there...
you can create a procedure like this:
create procedure sp_updateThis
#something varchar(5),
#active char(1)
AS
Begin
if #active ='y'
begin
update yourTable set that=#something
end
else
update myTable set this=#something
update yourTable set that=#something
end
go

trigger at particular column with condition

I want to check a Column value when update.If its match insert into another table.
My Tables:
My trigger:
CREATE TRIGGER tr_test
ON test1
FOR UPDATE
AS
SET nocount ON
IF ( Update(sname) )
DECLARE #Name NVARCHAR
DECLARE #id INT
SET #id=##IDENTITY
SET #Name=(SELECT sname
FROM test1
WHERE id = #id)
IF( #Name = 'Paras' )
BEGIN
INSERT INTO test2
(loginfo)
VALUES ('success')
END
And my update query is:
update Test1 set Sname='Paras' where ID=1
When I run this update query Nothing is happen.Test2 table is empty.I think problem is ##IDENTITY but not sure.Thanks.
Try this:
CREATE TRIGGER tr_test
ON test1
FOR UPDATE
AS
SET nocount ON
IF ( Update(sname) )
DECLARE #Name NVARCHAR
DECLARE #id INT
SET #id=(select id from inserted)
SET #Name=(SELECT sname
FROM inserted
WHERE id = #id)
IF( #Name = 'Paras' )
BEGIN
INSERT INTO test2
(loginfo)
VALUES ('success')
END
But it's better to do this, an update can update many rows, the above will fail if UPDATE matches many rows, use EXISTS:
CREATE TRIGGER tr_test
ON test1
FOR UPDATE
AS
SET nocount ON
IF( EXISTS(select * From inserted where sname = 'Paras' ) )
BEGIN
INSERT INTO test2
(loginfo)
VALUES ('success')
END
inserted table is the name of the table where the UPDATE's new values goes, deleted table is the name of the table where UPDATE's old values goes