Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Administration (2000)
 MSDTC on server 'Server 1' is unavailable.

Author  Topic 

Ken Blum
Constraint Violating Yak Guru

383 Posts

Posted - 2005-05-04 : 13:24:02
I've created the following Insert Trigger on a table on Server1, which calls a SPROC on Server2. I have successfully linked the servers and can execute the sproc on Server2 while logged into Server1 via QA.

When I insert a record into the table, I get the above error 8501. Do I really need MSDTC to do this, or is my trigger wrong? If so, how do I install MSDTC, and what are the implications of doing so?

How can I rewrite the trigger to call the sproc for each row of Inserted data?


CREATE TRIGGER [Astea_Insert] ON dbo.TrackData
AFTER INSERT
AS

/* Call Stored Procedure in AsteaSQL Server */


DECLARE @Astea_Serial varchar(30)
DECLARE @Astea_Error_Code varchar(8)
DECLARE @Astea_Text varchar(254)
DECLARE @Astea_DT datetime
DECLARE @Astea_ErrorLevel int
DECLARE @Result int
DECLARE @ErrorVal int

SELECT @Astea_Serial = i.SerialNumber FROM Inserted i
SELECT @Astea_Error_Code =i.ErrorCode FROM Inserted i
SELECT @Astea_Text = i.Text FROM Inserted i
SELECT @Astea_DT = i.Time_Stamp FROM Inserted i
SELECT @Astea_ErrorLevel = i.ErrorLevel FROM Inserted i

IF @Astea_ErrorLevel < 3 OR @Astea_Serial = 'REMTEST'
RETURN

EXECUTE [Server2].Enov_Dev.dbo.fj_create_monitor @Astea_Serial,@Astea_Error_Code,@Astea_Text,@Astea_DT,@Result OUTPUT

Select @ErrorVal = @@ERROR

/* Record Error for Diagnostics */
IF (@ErrorVal != 0 OR @Result != 0)
BEGIN
INSERT INTO SysError (IDKey,IDKey2,RetVal,Msg)
Select i.TrackDataIDKey,i.DB2_Key,@ErrorVal,'ASTEAINS'
FROM inserted i
END


Here's the sproc that's being called on Server2...


CREATE PROCEDURE fj_create_monitor
@serial_no varchar(30), /* Serial Number */
@error_code varchar(8), /* Error Code */
@comment varchar(254), /* Comment */
@created_at datetime, /* timestamp */
@l_return integer output
as


INSERT INTO fj_monitor
( comment,
created_at,
error_code,
serial_no )
VALUES ( @comment,
@created_at,
@error_code,
@serial_no)
IF @@error <> 0
BEGIN
select -1
return
END

--Commit
select 0
return
GO


TIA,

Ken

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-05-04 : 15:16:05
You need MSDTC since you are using linked servers. Make sure that the Distributed Transaction Coordinator service is started on both servers.

Tara
Go to Top of Page

Ken Blum
Constraint Violating Yak Guru

383 Posts

Posted - 2005-05-04 : 15:32:49
Thanks Tara.

1. Are there any other implications when starting MS DTC service I should know about?

2. Any advice on How I could rewrite the trigger to call the sproc for each row of Inserted data?

3. Is there any other way to do this without using linked servers?
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-05-04 : 15:36:22
1. None that I am aware of. We have this service started on all of our database servers
2. This type of thing requires looping.

BTW, you have a fundamental problem with your trigger. A trigger fires for the entire insert and not one row at a time. You are using variables, so you are only going to be able to process the last row in the inserted batch. For more information, please see my blog entry:
http://weblogs.sqlteam.com/tarad/archive/2004/09/14/2077.aspx

Tara
Go to Top of Page

Ken Blum
Constraint Violating Yak Guru

383 Posts

Posted - 2005-05-04 : 15:42:43
Boy, you are quick. I added another question 3, but I think you answered it in #1.

Your mentioning of the fundamental problem is what I am asking about in question 2. How do I "loop" through the Inserted table calling the sproc for each row?
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-05-04 : 15:47:12
You'd have to use a WHILE loop or a cursor. This will cause performance problems as looping in a trigger will cause the transaction to have to wait to complete.

I'd rewrite your remote stored procedure so that it can accept a CSV list of values as inputs and then insert them all at once. This way you wouldn't need the loop to call the proc.

You might consider changing your application so that it handles the insert into the remote database instead of using a trigger. So your application would do both inserts. If the destination table is similar to the source table, you might also consider using replication.

Tara
Go to Top of Page

Ken Blum
Constraint Violating Yak Guru

383 Posts

Posted - 2005-05-04 : 15:52:34
Unfortunately the Remote proc is not under my control. However, the application that inserts data into the table that is calling the SPROC is under my control. As long as I never call a batch insert I believe the trigger will work as written, shouldn't it?
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-05-04 : 15:54:36
Yes it would. But I'd hate to assume that a batch insert never occurs.

If the application is under your control, you might consider just doing this from your application then as that'll be faster than a trigger looping.

Tara
Go to Top of Page

Ken Blum
Constraint Violating Yak Guru

383 Posts

Posted - 2005-05-04 : 16:00:42
Yup, we all know what happens when one ass-u-me's!

Thanks for the advice once again Tara.
Go to Top of Page
   

- Advertisement -