Sql Trigger on a view does not getting triggered - sql-server

I have a view getting data from others views when data is inserted in this specific view as show bellow need to insert in table vendas ref(nvarchar(50)) and Estado(bool).
ALTER TRIGGER [dbo].[TGR_VENDAS]
ON [dbo].[VendasFinal]
INSTEAD OF INSERT
AS
BEGIN
DECLARE
#Ref nvarchar(50),
#EstadoString nvarchar(50)
SELECT #Ref = i.ref, #EstadoString = i.ESTADO
FROM inserted i
if(#EstadoString = 'Em Aberto')
BEGIN
INSERT INTO dbo.Vendas
(ref, Estado)
VALUES
(#Ref ,0);
END
ELSE
BEGIN
INSERT INTO dbo.Vendas
(ref, Estado)
VALUES
(#Ref ,1);
END
END
It's running on a MS Sql Server 11.0.
Thanks in advance.

You don't need a cursor here. You just need to use a case expression. Your posted trigger can be simplified to this. It handles any number of rows and the logic you have in the existing code.
ALTER TRIGGER [dbo].[TGR_VENDAS]
ON [dbo].[VendasFinal]
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO dbo.Vendas
(
ref
, Estado
)
SELECT i.ref
, case when i.ESTADO = 'Em Aberto' then 0 else 1 end
from inserted i

Related

Insert and update multiple records via same stored procedure

I created this stored procedure to go through all the records in the table comparing the id (primary key) if exists and the records changed, make the necessary changes & update the record.
If the id is not in the table then insert the record. This stored procedure
compiles fine, but doesn't seem to work properly. Does this need a while loop?
ALTER PROCEDURE [dbo].[SMLineUpdate]
(
#id [int],
#Payroll_Id [int],
#ProductCode nvarchar(255),
#Description nvarchar (255),
#Qty nvarchar(255)
)
AS
IF EXISTS (SELECT Id from Smline where #id = Id) BEGIN
update dbo.SmLine
Set [Payroll_Id] = #Payroll_Id
, ProductCode = #ProductCode
, Description = #Description
, Qty = #Qty
END ELSE BEGIN
INSERT INTO SmLine ([Payroll_Id], [ProductCode], [Description], [Qty])
VALUES (#Payroll_Id, #ProductCode, #Description, #Qty)
END
Your update query is missing a where condition
update dbo.SmLine
Set [Payroll_Id] = #Payroll_Id
,ProductCode = #ProductCode
,Description = #Description
,Qty = #Qty
WHERE Id = #Id -- the query missed this where condition
IF EXISTS(SELECT Id from Smline where Id =#id)
BEGIN
update dbo.SmLine
Set [Payroll_Id]= #Payroll_Id
,ProductCode= #ProductCode
,Description = #Description
,Qty = #Qty
WHERE Id = #Id
END
ELSE
BEGIN
INSERT INTO SmLine ([Payroll_Id],[ProductCode],[Description],[Qty])
VALUES (#Payroll_Id,#ProductCode ,#Description,#Qty)
END
Your SP does not meet the requirement of insert multiple records. It works only for a single record update or inserts, you have to pass multiple id's and values respectively for update multiple so use a different approach like XML as an input parameter so u can simply do this operation for multiple by extracting the XML data.
Your update statement lacks a where statement. That is a major 'no-no', as it will (god forbid...) update all lines in the table.
Your insert statement lacks an identity insert, so consider the case where you are trying to update/insert id=5, but by now this line is deleted (not found in the where), and ids are much bigger. you would search for it -- > not find, and insert a new line (say id=101), then look for id=5 again, not find it again, and insert it again (say id=102), and so on... I don't think that's what you intended. Consider a Merge statement (when matched/when not matched) and get the best of both worlds. Also consider not deleting from the table, and instead add an 'IsDeleted' column (which allows 'reviving' a deleted row).

SQL Server INSERT in an AFTER UPDATE Trigger

I'm new to SQL Server, and I'm trying to build a simple update trigger that writes a row to a staging table whenever the column ceu_amount is updated from zero to any number greater than zero.
From using PRINT statements, I know that the variables are containing the correct values to execute the INSERT statement, but no rows are being inserted.
Can you help?
CREATE TRIGGER [dbo].[TRG_Product_Function_Modified] ON [dbo].[Product_Function]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
--
-- Variable definitions
--
DECLARE #product_code_new as varchar(31)
DECLARE #product_code_old as varchar(31)
--
-- Check if the staging table needs to be updated.
--
SELECT #product_code_new = product_code FROM Inserted where ISNULL(ceu_amount,0) > 0;
SELECT #product_code_old = product_code FROM Deleted where ISNULL(ceu_amount,0) = 0;
IF #product_code_new IS NOT NULL
AND #product_code_old IS NOT NULL
INSERT INTO Product_Function_Staging VALUES (#product_code_new,CURRENT_TIMESTAMP);
END;
This part of code looks suspicious to me..
SELECT #product_code_new = product_code FROM Inserted where ISNULL(ceu_amount,0) > 0;
SELECT #product_code_old = product_code FROM Deleted where ISNULL(ceu_amount,0) = 0;
IF #product_code_new IS NOT NULL
AND #product_code_old IS NOT NULL
INSERT INTO Product_Function_Staging VALUES (#product_code_new,CURRENT_TIMESTAMP);
The above will work fine ,if there is only one row updated,what if there is more than one value..the product_code will default to last value
You can change the above part of code to below
Insert into Product_Function_Staging
select product_code ,CURRENT_TIMESTAMP from inserted where product_code is not null
You will get undetermined values for #product_code_new if there are more than one rows updated with ceu_amount>0; Similar for #product_code_old if more than one rows updated with ceu_amount NULL or equal 0.
Can you post some sample data?
I would not use variables like that in a trigger, since what causes the trigger could be an update to more than one row, at which point you would have multiple rows in your updated and deleted tables.
I think we can more safely and efficiently make this insert with one simple query, though I'm assuming you have a unique key to use:
CREATE TRIGGER [dbo].[TRG_Product_Function_Modified] ON [dbo].[Product_Function]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Product_Function_Staging
SELECT i.product_code, CURRENT_TIMESTAMP
FROM inserted i
JOIN deleted d ON i.product_code = d.product_code -- assuming product_code is unique
WHERE i.ceu_amount > 0 -- new value > 0
AND ISNULL(d.ceu_amount, 0) = 0; -- old value null or 0
END;
I'm not sure where you need to check for nulls in your data, so I've made a best guess in the where clause.
Try using this
CREATE TRIGGER [dbo].[Customer_UPDATE]
ON [dbo].[Customers]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #CustomerId INT
DECLARE #Action VARCHAR(50)
SELECT #CustomerId = INSERTED.CustomerId
FROM INSERTED
IF UPDATE(Name)
BEGIN
SET #Action = 'Updated Name'
END
IF UPDATE(Country)
BEGIN
SET #Action = 'Updated Country'
END
INSERT INTO CustomerLogs
VALUES(#CustomerId, #Action)
END

Create Transaction and Trigger on a field

Please am new in vb.net and sql server, I have created a two tables in database called Service and Trans.
Create Table Service(
ServiceID int,
ServiceName varchar(30),
ServiceStartValue int
);
Create Table Trans(
EntryTS datetime,
EntryCounter int,
ServedTS datetime,
ServedCounter int,
Skipped int
);
I am trying to create a 'transaction and trigger' that will check and update ServedCounter based on the values in EntryCounter upon ServiceID which the update statement must not allow the ServedCounter > EntryCounter.
I don't quite understand the full requirement, but here's how you can prevent a update (or insert) from happening with a trigger.
CREATE TRIGGER Trans_upd_trg ON Trans AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
--Don't allow the update
IF EXISTS(SELECT 1 FROM inserted WHERE ServedCounter > EntryCounter)
RAISERROR ('ServedCounter > EntryCounter', 16, 1 );
END
GO
Within the context of the trigger you have two logical tables, INSERTED, and DELETED.
These tables contain the old and new values. (deleted is empty for a insert operation)
Hope that helps.
Use a Instead Of Trigger
CREATE TRIGGER Trans_upd_trg
ON Trans
Instead OF INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT *
FROM inserted
WHERE ServedCounter > EntryCounter)
AND EXISTS (SELECT *
FROM deleted)
UPDATE A
SET EntryTS = I.EntryTS,
EntryCounter = I.EntryCounter,
ServedTS = I.ServedTS,
ServedCounter = I.ServedCounter,
Skipped = I.Skipped
FROM Trans A
JOIN inserted I
ON A.EntryTS = I.EntryTS
AND A.ServedTS = I.ServedTS
WHERE i.ServedCounter > i.EntryCounter
ELSE
INSERT INTO Trans
SELECT *
FROM inserted
WHERE ServedCounter > EntryCounter
END
GO

SQL Server : Triggers for Insert

create table tab(id int identity,task_id int,task_descp varchar(10),task_code varchar(10))
insert into tab values(7,'BUS','B')
insert into tab values(3,'CAR','C')
create table tab_detail( task_descp varchar(10),task_code varchar(10),color varchar(10))
create trigger tab_trigger on tab for insert as
declare #task_descp varchar(10)
declare #task_code varchar(10)
declare #task_id int
set #task_descp=i.task_descp from inserted i
set #task_code=i.task_code from inserted i
set #task_id=i.task_id from inserted i
if(#task_id=7)
insert into tab_detail values(#task_descp,#task_code,'BLUE')
if(#task_id=3)
insert into tab_detail values(#task_descp,#task_code,'GREEN')
go
I want to create a trigger for table tab where if I insert a record based on the task_id column a record has to be inserted into another table tab_detail.
When executing this I get this error:
Incorrect syntax near the keyword 'from'
Instead of:
set #task_descp=i.task_descp from inserted i
Try this:
select #task_descp=i.task_descp from inserted i
Or you could do this:
create trigger tab_trigger on tab for insert as
insert into tab_detail
select task_descp, task_code, case #task_id when 7 then 'BLUE' else 'GREEN' end
from inserted
where taskid in (7,3)
go
Change the SET to SELECT. Also, inserted is a recordset, not a single value. Fixing the code issue still might result in a run time issue!
This code should work fine for a recordset of information.
CREATE TRIGGER tab_trigger ON tab FOR INSERT AS
BEGIN
-- nothing to do?
IF (##rowcount = 0) RETURN;
-- do not count rows
SET NOCOUNT ON;
-- inserted data
INSERT INTO tab_detail
SELECT
i.task_descp,
i.task_code,
CASE i.taskcode
WHEN 7 THEN 'BLUE'
WHEN 3 THEN 'GREEN'
ELSE ''
END
FROM inserted i
WHERE i.task_code in (3, 7)
END
GO

how to check data if exists "type of table" in stored procedure

I have created a type in sql server 2008 for to pass datatable to stored procedure.
My SP works ok but how can I check data if exists in the table?
(for example: check detailid or id
if exists: update them
if not exists: insert new )
here is my SP:
ALTER PROCEDURE [dbo].[Insert_Data]
(
#empinfo myType READONLY
)
AS
BEGIN
SET NOCOUNT ON;
Insert into TableEmp(ID, DetailID, Text)
select id, detailid, text from #empinfo
END
Thnx all
ALTER PROCEDURE [dbo].[Insert_Data]
(
#empinfo myType READONLY
)
AS
BEGIN
SET NOCOUNT ON;
MERGE TableEmp AS t
USING (select id, detailid, [text] from #empinfo) AS s
ON s.ID = t.ID
WHEN MATCHED THEN
UPDATE SET t.detailid = s.detailid,
t.[text] = s.[text]
WHEN NOT MATCHED THEN
INSERT(id, detailid, [text])
VALUES(s.id, s.detailid, s.[text]);
END
You can declare a variable and count the records in the table.
DECLARE #count INT
SET #count = (SELECT COUNT(ID)
FROM TableEmp)
-- Do Something with the results
So then using conditional logic, you can do something with the count to accomplish different results.
IF #count = 0
BEGIN
-- Do Something cool like insert data
END
ELSE
BEGIN
-- Do Something else like update data
END
This is a simple example where you can search for a specific record and update it. If you need to update many records, then you can use cursors and iterate through the required records and update what you need.
More information about cursors can be found here:
http://technet.microsoft.com/en-us/library/ms180169.aspx

Resources