How could I solve " you can't chang 'dbo.tb_dept_change' , because it is a Incompatible object types"? - sql-server-2014

I have two tables, they are dbo.tb_dept_change and dbo.tb_employee. I need to alter the trigger, but it notices 消息 2010,级别 16,状态 1,过程 tb_dept_change,第 21 行无法对 'dbo.tb_dept_change' 进行更改,因为它是不兼容的对象类型.
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tb_dept_change] ON [dbo].[tb_employee]
FOR UPDATE
AS
if ( COLUMNS_UPDATED() &7) >0
BEGIN
if ((select employee_dept from Deleted ) <> (select employee_dept from Inserted))
begin
insert into tb_dept_change
(ch_date)
values(getdate())
update tb_dept_change set ch_source =Deleted.employee_dept, ch_duty_source = Deleted.employee_duty from Deleted
update tb_dept_change set ch_destination = Inserted.employee_dept, ch_duty_Destination = Inserted.employee_duty from Inserted
update tb_dept_change set ch_employee = Deleted.employee_id from Deleted

Related

convert sql server stored procedure to MySQL(xampp)

I am trying to implement a procedure within mysql(XAMPP). Thing is i have written my stored procedure in SQL SERVER I am not sure if this is an appropriate situation for a migrating to phpmyadmin but it should be converted to xampp and I apologize if this is extremely simple but this is my first run at procedures.
If somebody could please tell me what should i do so, it would be much appreciated.
Thanks! Here is my sql server stored procedure
BEGIN TRAN
GO
GO
create PROC calcPro
(
#p_Date DATE
)
AS
BEGIN
INSERT INTO calcula (PID)
SELECT PID FROM products WHERE PID NOT IN (SELECT PID FROM calcula)
CREATE TABLE #tmpCalc-- IF NOT EXISTs-->
(
PID INT, Date1 DATE, Date2 DATE,SaleDate DATE,[Days] INT,total_days int,depreciation NUMERIC(20,2),
depcur_value NUMERIC(20,2),next_diffdays int,salestatus int, FLAG CHAR(1)
)
INSERT INTO #tmpCalc (PID, Date1, Date2,total_days,depreciation,SaleDate,salestatus)
SELECT A.pid, A.added_date, #p_Date, c.category_life, A.depre, sale_Date, A.sale_status
FROM products A, calcula B,categories c
WHERE A.pid=B.pid and a.cid=c.cid
UPDATE #tmpCalc SET [Days]=datediff(dd,Date1,Date2)
UPDATE #tmpCalc SET [Days]=0,next_diffdays=datediff(dd,Date1,SaleDate) where [Days] <0
--UPDATE #tmpCalc SET next_diffdays=0 where Date1 < '2018-03-31'
UPDATE #tmpCalc SET depcur_value=((CONVERT(numeric(20,2),depreciation)/total_days)*[Days])
--UPDATE #tmpCalc SET wtvalue=((CONVERT(numeric(20,2),b.depre)/c.category_life)*a.[Days])
--FROM #tmpCalc A, products B, categories C
--WHERE A.pid=b.pid and b.cid=c.cid
UPDATE calcula SET yEnd=A.[Days],rem_days = A.total_days - [Days],cur_depre = A.depcur_value,cur_wrvalue = A.depreciation-A.depcur_value
FROM #tmpCalc A, calcula B
WHERE A.pid=B.pid
UPDATE calcula SET yEnd=0,rem_days=0,cur_wrvalue =0 WHERE yEnd <= 0
DECLARE #SaleDt INT, #YendDt INT, #L_PID INT, #Date2 DATE, #DepValue1 NUMERIC(20,2), #DepValue2 NUMERIC(20,2),
#DepValue NUMERIC(20,2)
SELECT #SaleDt=COUNT(*) FROM calcula WHERE sale_status='1'
SELECT #YendDt=COUNT(*) FROM calcula WHERE sale_status='0'
WHILE #SaleDt > 0
BEGIN
SELECT #L_PID=PID,#Date2=Date1 FROM #tmpCalc WHERE salestatus='1' AND FLAG IS NULL
SELECT #DepValue1=A.depreciation,#DepValue2=B.cur_wrvalue FROM #tmpCalc A, calcula B WHERE A.PID=B.pid AND A.PID=#L_PID
IF #DepValue2='0'
BEGIN
SET #DepValue=#DepValue1
END
ELSE
IF #DepValue2!='0'
BEGIN
SET #DepValue=#DepValue2
END
IF #Date2<='2018-03-31'
BEGIN
SET #Date2='2018-04-01'
END
UPDATE #tmpCalc SET next_diffdays=datediff(dd,#Date2,SaleDate) where pid=#L_PID
UPDATE calcula SET next_wtvalue=(#DepValue-next_depre) where pid=#L_PID
SET #SaleDt=#SaleDt-1
UPDATE #tmpCalc SET FLAG='Y' WHERE PID=#L_PID
SET #L_PID=''
SET #Date2=''
SET #DepValue2='0'
SET #DepValue1='0'
SET #DepValue='0'
END
WHILE #YendDt > 0
BEGIN
SELECT #L_PID=PID,#Date2=Date1 FROM #tmpCalc WHERE salestatus='0' AND FLAG IS NULL
SELECT #DepValue1=A.depreciation,#DepValue2=B.cur_wrvalue FROM #tmpCalc A, calcula B WHERE A.PID=B.pid AND A.PID=#L_PID
IF #DepValue2='0'
BEGIN
SET #DepValue=#DepValue1
END
ELSE
IF #DepValue2!='0'
BEGIN
SET #DepValue=#DepValue2
END
IF #Date2<='2018-03-31'
BEGIN
SET #Date2='2018-04-01'
END
UPDATE #tmpCalc SET next_diffdays=datediff(dd,#Date2,'2019-03-31') where pid=#L_PID
UPDATE calcula SET next_wtvalue=(#DepValue-next_depre) where pid=#L_PID
SET #YendDt=#YendDt-1
UPDATE #tmpCalc SET FLAG='Y' WHERE PID=#L_PID
SET #L_PID=''
SET #Date2=''
SET #DepValue2='0'
SET #DepValue1='0'
SET #DepValue='0'
END
UPDATE calcula SET next_depre = (A.depreciation/A.total_days) * A.next_diffdays,accumdepre=b.cur_depre+b.next_depre
FROM #tmpCalc A, calcula B
WHERE A.pid=B.pid
SELECT * FROM #tmpCalc
--select p.pid,c.pid,p.product_name,p.depre,c.yEnd,c.rem_days,c.cur_depre from products p,calcula c where p.pid = c.pid
select * from calcula
END
GO
EXEC calcPro '2018-03-31'
GO
--select * from calcula
--select * from products
--select * from categories
GO
--ROLLBACK TRAN
commit
In order to change a store procedure from MSSQL to MySQL, you should inspect the whole script taking into account the sintax changes that exists between the two languages.
Looking to your SP, here are some things that need to be change to make it work in MySQL (there are probably more):
Create the SP with:
DELIMITER //
CREATE PROCEDURE calcPro()
BEGIN
...
END//
You have to use DELIMITER to avoid unexpected syntax erros. See https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
The creation of temporary tables is different in MySQL:
CREATE TEMPORARY TABLE tmpCalc (PID INT,....)
The UPDATE ... FROM ... syntax is not valid in MySQL, you should try something like:
UPDATE calcula B, #tmpCalc A
SET yEnd=A.[Days]
,rem_days = A.total_days - [Days]
,cur_depre = A.depcur_value
,cur_wrvalue = A.depreciation-A.depcur_value
WHERE A.pid=B.pid
Setting variables:
One variable:
SET #SaleDt = (SELECT COUNT(*) FROM calcula WHERE sale_status='1');
Multiple variables:
SELECT PID, Date1
INTO #L_PID, #Date2
FROM #tmpCalc
WHERE salestatus='1'
AND FLAG IS NULL;
The WHILE syntax is different. Check https://dev.mysql.com/doc/refman/8.0/en/while.html
WHILE #SaleDt > 0 DO
...
END WHILE;
Even executing the SP is different:
CALL calcPro('2018-03-31');

Dynamic name tablе in trigger

There is a trigger that copies columns from one table to another. How do I assign a table name to a dynamic variable #nametable?
Every day the name of the table changes depending on the current date.
USE dbo;
DROP TRIGGER IF EXISTS `update_test`;
GO
DELIMITER |
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
DECLARE nametable VARCHAR(128);
SET #nametable =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
INSERT INTO `dbo`.`nametable` SET
`TIME_` =NEW.`recorded`,
`P1` = NEW.`value1`
ON DUPLICATE KEY UPDATE
`TIME_` = NEW.`recorded`,
`P1` = NEW.`value1`;
END;
Have error ERROR 1146: Table 'dbo.nametable' doesn't exist
I decided to do so as a temporary solution:
CREATE TRIGGER `update_test` AFTER INSERT ON `hello_send`
FOR EACH ROW
BEGIN
SET #dateNameTableNOW =(DATE_FORMAT(NOW(),"%d%m%Y_v"));
SET #dateNameTableSELECT1 = '06122017_v';
SET #dateNameTableSELECT2 = '07122017_v';
IF(#dateNameTableNOW = #dateNameTableSELECT1) THEN
INSERT INTO dbo.06122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
IF(#dateNameTableNOW = #dateNameTableSELECT2) THEN
INSERT INTO dbo.07122017_v SET TIME_=NEW.recorded, P1 = NEW.value1 ON DUPLICATE KEY UPDATE TIME_ = NEW.recorded, P1 = NEW.value1;
END IF;
END;

SQL Server 2008 :: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >=

I have [ReconcileUserInformationComputed] trigger on Userinformation table
Userinformation table has below rows
[ID] ,[CompanyID] ,[Status] ,[FirstName] ,[LastName]
UserinformationComputed table has below rows
[id] ,[CompanyID] ,[law_id] ,[Status] ,[FirstName] ,[LastName]
Below is my trigger
USE [einvoice]
GO
/****** Object: Trigger [dbo].[ReconcileUserInformationComputed] Script Date: 08/27/2014 10:53:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[ReconcileUserInformationComputed] ON [dbo].[UserInformation] AFTER INSERT,DELETE,UPDATE
AS
IF ##ROWCOUNT = 0 -- exit trigger when zero records affected
BEGIN
RETURN
END
SET NOCOUNT ON;
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
--UPDATE
UPDATE [dbo].[UserInformationComputed]
SET -- use new values from inserted
CompanyID = (SELECT CompanyID from inserted),
law_id = (SELECT ID FROM inserted),
Status = (SELECT Status FROM inserted),
FirstName = (SELECT FirstName FROM inserted),
LastName = (SELECT LastName FROM inserted),
WHERE -- use original values from deleted
law_id = (SELECT ID FROM deleted)
END
ELSE
BEGIN
--INSERT
INSERT INTO [dbo].[UserInformationComputed] (CompanyID,law_id,Status,FirstName,LastName)
SELECT CompanyID,id,Status,FirstName,LastName) FROM inserted
END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
--DELETE
DELETE FROM [dbo].[UserInformationComputed]
WHERE law_id = (SELECT id FROM deleted)
END
when try to update multiple users on Userinformation am getting
below error
Msg 512, Level 16, State 1, Procedure ReconcileUserInformationComputed, Line 16
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I made the changes as per the answer it worked for the above trigger but same changes didnt work for another trigger
ALTER TRIGGER [dbo].[ReconcileCrossRefComputed] ON [dbo].[CrossRef] AFTER INSERT, UPDATE, DELETE
AS
IF ##ROWCOUNT = 0 -- exit trigger when zero records affected
BEGIN
RETURN
END
SET NOCOUNT ON;
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
--UPDATE
UPDATE [dbo].[CrossRefComputed]
SET -- use new values from inserted
SenderId = inserted.SenderId,
ReceiverId = inserted.ReceiverId,
ForeignRef = inserted.ForeignRef,
PolicyID = inserted.PolicyID,
From inserted
WHERE -- use original values from deleted
[CrossRefComputed].SenderId = inserted.SenderId
AND [CrossRefComputed].ReceiverId = inserted.ReceiverId
END
ELSE
BEGIN
--INSERT
INSERT INTO [dbo].[CrossRefComputed] (SenderId, ReceiverId, ForeignRef, PolicyID)
SELECT SenderId, ReceiverId, Effective, PolicyID FROM inserted
END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
--DELETE
DELETE FROM [dbo].[CrossRefComputed]
WHERE SenderId in (SELECT SenderId FROM deleted)
AND ReceiverId in (SELECT ReceiverId FROM deleted)
END
COuld anyone please help me how to fix the procedure to handle updating multiple records?
Be aware that an UPDATE or a DELETE can affect more than one record and your trigger will have to deal with them at once, in this case your "inserted" or "deleted" table will have more than one record.
You will have to use a join in your DML. Something like this:
UPDATE [dbo].[UserInformationComputed]
SET
CompanyID = inserted.CompanyID,
law_id = inserted.ID,
Status = inserted.Status,
FirstName = inserted.FirstName,
LastName = inserted.LastName
from inserted
WHERE
UserInformationComputed.law_id = inserted.ID
I haven't perfectly understood your UPDATE logic, so you'll have to adapt my code.
In your DELETE command you may have just to change "=" to "in":
DELETE FROM [dbo].[UserInformationComputed]
WHERE law_id in (SELECT id FROM deleted)
Take a look at this:
http://msdn.microsoft.com/en-us/library/ms190752.aspx

How can i create a trigger that will only update a record if the new record is different from the old record?

Question is create a trigger that will only update a record if the old record is different from the new. Can i get some help please i don't even know how to start the syntax apart from
CREATE TRIGGER update_marketingliste
ON marketing_list FOR UPDATE
AS
BEGIN
SELECT * FROM INSERTED
END
I am not sure what the schema is but the sample code below should help you to understand how this can be done.
SET NOCOUNT ON
GO
CREATE TABLE test(col1 int primary key , col2 int )
go
CREATE TRIGGER trg_test_upd on test
INSTEAD OF UPDATE
AS
BEGIN
IF EXISTS (
SELECT *
FROM Deleted del -- old value
INNER JOIN Inserted ins -- new value
on del.col1 = ins.col1
and del.col2 = ins.col2)
BEGIN
PRINT 'No Update'
RETURN --if old value is same as new value dont update
END
ELSE
BEGIN
UPDATE t1
set col2 = i.col2
from dbo.test t1
inner join inserted i
on t1.col1 = i.col1
END
END
go
Insert into test (col1, col2)
select 10, 10
go
update test
set col2 = 200
where col1 = 10
SELECT *
FROM TEST
--This would not do the update
update test
set col2 = 200
GO
Drop table test
go

SQL blocking with replication and triggers

I have a table that is replicated from Server A to Server B using transactional replication. I also have a INSERT & UPDATE trigger on the table on Server B. When the SQL Server Agent is replicating data, there are blocks, caused by the trigger.
Below are my triggers.
USE [STOREMAIN]
GO
/****** Object: Trigger [dbo].[UPD_tblReceivingHeaderStatus] Script Date: 08/16/2011 13:28:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[UPD_tblReceivingHeaderStatus]
ON [dbo].[tblReceivingHeader]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #SeqNum numeric ,#Location numeric
--get the seqnum & location from the inserted record
select #SeqNum = i.SeqNum, #Location = i.Location
from tblReceivingHeaderStatus D
left join inserted i on D.Location = i.Location and D.SeqNum = i.SeqNum
UPDATE tblReceivingHeaderStatus
SET
AdjTax = inserted.AdjTax,
AdjDeliveryFee = inserted.AdjDeliveryFee,
AdjDiscount = inserted.AdjDiscount,
AdjInvoiceTotal = inserted.AdjInvoiceTotal,
AdjItemCount= inserted.AdjItemCount,
AdjInvoiceInfo = inserted.AdjInvoiceInfo,
InvoiceAdjReason = ISNULL(inserted.InvoiceAdjReason,''),
PaidFlag = inserted.PaidFlag,
StartDate = inserted.StartDate,
CheckComments = inserted.CheckComments,
POeMailSent = case inserted.CheckComments
when '.' then 'P'
else ''
end,
PONumber = inserted.PONumber,
[Status] = inserted.[Status],
MiscFlag2 = 'T'
FROM
inserted
WHERE
inserted.seqnum = tblReceivingHeaderStatus.seqnum AND
inserted.location = tblReceivingHeaderStatus.location
;
--this assigns all inventory PO receivers to someone in pricing to approve
update tblReceivingHeaderStatus
set NextApprover = 1
from tblReceivingHeaderStatus
left join apvendp on vmvend = vendornum
where
recdevice = 'P' and
status = '1' and
NextApprover <> 1 and
vminex = 'I'
;
END
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
--------------------------------
USE [STOREMAIN]
GO
/****** Object: Trigger [dbo].[INS_INTO_tblReceivingHeaderStatus] Script Date: 08/16/2011 13:28:47 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[INS_INTO_tblReceivingHeaderStatus]
ON [dbo].[tblReceivingHeader]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #SeqNum numeric ,#Location numeric
--get the seqnum & location from the inserted record
select #SeqNum = i.SeqNum, #Location = i.Location
from tblReceivingHeaderStatus D
left join inserted i on D.Location = i.Location and D.SeqNum = i.SeqNum;
INSERT INTO storemain..tblReceivingHeaderStatus
( SeqNum, VendorNum, InvoiceNum, InvoiceTotal, ItemCount, InvoiceDate, Status, Location, AdjTax, AdjDeliveryFee, AdjDiscount, AdjInvoiceTotal,
AdjItemCount, AdjInvoiceInfo, Tax, DeliveryFee, Discount, ApprovedTime, ApprovedDate, ApprovedBy, InvoiceAdjReason, SentTo400, TimeDateSent, PaidFlag,
StartDate, CheckComments, DrayEnteredBy, NextApprover, PONumber, recDevice, SalesTaxFlag, FreightFlag, MiscFlag1, MiscFlag2, MiscFlag3, MiscChar1,
MiscChar2, MiscChar3, MiscNumber1, M
Maybe implementing dirty reads in your query might help?
select id, description from sometable (nolock)
saying that, im not 100% of the impact of dirty reads in the sort of environment you are in, so it might be worth investigating further.
The tables could be locking depending on the server load required when copying data from one server to another, as intensive selects can (i believe) cause locks if there are large enough queries being run. dirty reads mitigate this problem somewhat, however can have consequences in that you can get stale data. Could it be worth trying a different form of replication?
Anyone/everyone, please correct me if im wrong and barking up the wrong tree :)