dbaSQL
asked on
Two insert procedure revisions
I need some pretty decent help w/the insert proc below. in short, we trade electronically, sometimes there is a need to manually insert trades into the database, and we have three datasets that are to be kept in synch at all times. right now, if/when it is needed, the proc below is fired three times to hit the three different servers. (very problematic) i have several other procedures similar in this nature, that need to impact all three instances --- i fire them off with a 'driver'. This is a small example of one of my driver procs:
IF EXISTS(SELECT 1 FROM Database.dbo.Current WHERE tradetime >=@tradetime and ordernumber=@ordernumber)
BEGIN
INSERT Database.dbo.AuditTrail (ActionDate,ActionType,Act ionSource, OrderNumbe r,Old,New, UserID,Hos tname)
SELECT CURRENT_TIMESTAMP,'Quantit y',CONVERT (char(20), SERVERPROPERTY('servername ')),@order number,qua ntity,@new qty,SYSTEM _USER,HOST _NAME()
FROM Database.dbo.Current
WHERE tradeTime >=@tradetime
AND ordernumber = @ordernumber
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
END
You see, the drivers are coded such that they invoke the editing procedure(s) on the three instances. my people invoke the driver once, it hits all three boxes. i need to do that w/this insert procedure, but i am struggling around all of the defaults. Is anyone able to help me put a driver around this?
That's problem #1. The second issue is a little harder to describe. It may simply not be an option, but I need to check. As you can see, @source defaults to 'FImporter'. Of course, this can be passed in, if needed. I was wondering, IF @source = 'ROLLTRADE', can I go just a step further? If @source=ROLLTRADE, the user also needs to submit a settledate for the trade they just inserted. (@settledate, @ordernumber) I want the gui to do this with as little intervention from the trading desk, as possible. From their point of view, they enter all the information at once, and hit one button to submit. But, IF @source = ROLLTRADE, is there anyway I can then proceed to retrieve the ordernumber (just created) and pass it with @SettleDate to another proc, that will write to another table, without any intervention on the part of the desk?
both are very important, though #2 is a tiny bit more pressing than #1. any suggestions?
CREATE PROCEDURE dbo.insertProc
(
@MsgID varchar(175),
@UserId varchar(16),
@AcctId varchar(16),
@PrevOrderNo varchar(32)='?',
@EndPoint varchar(8),
@Symbol varchar(25),
@BuySell char(1),
@Quantity int,
@Price decimal(18,8),
@TradeTime datetime=NULL,
@ClearingFee int = 0,
@LiquidityFlag char(4)='?',
@Client varchar(32)='MET',
@OrderNumber varchar(100),
@OrigOrderNo varchar(32)='?',
@BasketId char(12)='?',
@BasketNumber varchar(15)='0',
@Quantity bigint=NULL,
@ExecutedQuantity bigint=NULL,
@LeavesQuantity bigint=0,
@OrderType char(1)='L',
@LimitPrice decimal(18,8)=NULL,
@AvgFillPrice decimal(18,8)=NULL,
@OrderStatus varchar(4)='FILL',
@StopPrice decimal(18,8)=0.0,
@TimeInForce varchar(5)='DAY',
@cntrpartyID varchar(15)='?',
@HostName varchar(50)=NULL,
@OrderMarking char(1)=NULL,
@Source varchar(15)='FImporter'
)
AS
SET NOCOUNT ON
BEGIN
--if @tradetime isn't passed, default to today
IF (@TradeTime IS NULL)
SET @TradeTime = GETDATE()
--set these all for defaults
SET @quantity = COALESCE(@quantity, @quantity)
SET @executedquantity = COALESCE(@quantity, @executedquantity)
SET @limitprice = COALESCE(@price,@limitpric e)
SET @avgfillprice = COALESCE(@price,@avgfillpr ice)
SET @hostname = HOST_NAME()
BEGIN TRANSACTION
IF DATEDIFF(day,@TradeTime,ge tdate())=0
/* if date is current day, insert only into Database.dbo.Current */
BEGIN
INSERT Database.dbo.Current (
[MsgID], [UserId],[AcctId],[PrevOrd erNo],[End Point],[Sy mbol],[Buy Sell],[Qua ntity],[Pr ice],[Trad eTime],[Cl earingFee] ,
[LiquidityFlag],[Client],[ OrderNumbe r],[OrigOr derNo],[Ba sketId],[B asketNumbe r],[Quanti ty],[Execu tedQuantit y],[Leaves Quantity], [OrderType ],
[LimitPrice],[AvgFillPrice ],[OrderSt atus],[Sto pPrice],[T imeInForce ],[CntrPar tyId],[Hos tName],[Or derMarking ],[Source] )
VALUES (
@MsgId,@UserId,@AcctId,@Pr evOrderNo, @EndPoint, @Symbol,@B uySell,@Qu antity,@Pr ice,@Trade Time,@Clea ringFee,
@LiquidityFlag,@Client,@Or derNumber, @OrigOrder No,@Basket Id,@Basket Number,@Qu antity,@Ex ecutedQuan tity,@Leav esQuantity ,@OrderTyp e,
@LimitPrice,@AvgFillPrice, @OrderStat us,@StopPr ice,@TimeI nForce,@cn trpartyID, @HostName, @OrderMark ing,@Sourc e )
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Current.',16, -1)
RETURN
END
END
ELSE
/* If date within current business week, insert into Database.dbo.Current AND Database.dbo.Historical */
IF DATEDIFF(day,@TradeTime,ge tdate()) BETWEEN 1 AND 7
BEGIN
INSERT Database.dbo.Current (
[MsgID], [UserId],[AcctId],[PrevOrd erNo],[End Point],[Sy mbol],[Buy Sell],[Qua ntity],[Pr ice],[Trad eTime],[Cl earingFee] ,
[LiquidityFlag],[Client],[ OrderNumbe r],[OrigOr derNo],[Ba sketId],[B asketNumbe r],[Quanti ty],[Execu tedQuantit y],[Leaves Quantity], [OrderType ],
[LimitPrice],[AvgFillPrice ],[OrderSt atus],[Sto pPrice],[T imeInForce ],[CntrPar tyId],[Hos tName],[Or derMarking ],[Source] )
VALUES (
@MsgId,@UserId,@AcctId,@Pr evOrderNo, @EndPoint, @Symbol,@B uySell,@Qu antity,@Pr ice,@Trade Time,@Clea ringFee,
@LiquidityFlag,@Client,@Or derNumber, @OrigOrder No,@Basket Id,@Basket Number,@Qu antity,@Ex ecutedQuan tity,@Leav esQuantity ,@OrderTyp e,@LimitPr ice,
@AvgFillPrice,@OrderStatus ,@StopPric e,@TimeInF orce,@cntr partyID,@H ostName,@O rderMarkin g,@Source )
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Current.',16, -1)
RETURN
END
INSERT Database.dbo.Historical (
[MsgID], [UserId],[AcctId],[PrevOrd erNo],[End Point],[Sy mbol],[Buy Sell],[Qua ntity],[Pr ice],[Trad eTime],[Cl earingFee] ,
[LiquidityFlag],[Client],[ OrderNumbe r],[OrigOr derNo],[Ba sketId],[B asketNumbe r],[Quanti ty],[Execu tedQuantit y],[Leaves Quantity], [OrderType ],
[LimitPrice],[AvgFillPrice ],[OrderSt atus],[Sto pPrice],[T imeInForce ],[CntrPar tyId],[Hos tName],[Or derMarking ],[Source] )
VALUES (
@MsgId,@UserId,@AcctId,@Pr evOrderNo, @EndPoint, @Symbol,@B uySell,@Qu antity,@Pr ice,@Trade Time,@Clea ringFee,
@LiquidityFlag,@Client,@Or derNumber, @OrigOrder No,@Basket Id,@Basket Number,@Qu antity,@Ex ecutedQuan tity,@Leav esQuantity ,@OrderTyp e,@LimitPr ice,
@AvgFillPrice,@OrderStatus ,@StopPric e,@TimeInF orce,@cntr partyID,@H ostName,@O rderMarkin g,@Source )
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Historical.', 16,-1)
RETURN
END
END
ELSE
/* If date older than current business week, only insert into Database.dbo.Historical.*/
IF DATEDIFF(day,@TradeTime,ge tdate())>7
BEGIN
INSERT Database.dbo.Historical (
[MsgID], [UserId],[AcctId],[PrevOrd erNo],[End Point],[Sy mbol],[Buy Sell],[Qua ntity],[Pr ice],[Trad eTime],[Cl earingFee] ,
[LiquidityFlag],[Client],[ OrderNumbe r],[OrigOr derNo],[Ba sketId],[B asketNumbe r],[Quanti ty],[Execu tedQuantit y],[Leaves Quantity], [OrderType ],
[LimitPrice],[AvgFillPrice ],[OrderSt atus],[Sto pPrice],[T imeInForce ],[CntrPar tyId],[Hos tName],[Or derMarking ],[Source] )
VALUES (
@MsgId,@UserId,@AcctId,@Pr evOrderNo, @EndPoint, @Symbol,@B uySell,@Qu antity,@Pr ice,@Trade Time,@Clea ringFee,
@LiquidityFlag,@Client,@Or derNumber, @OrigOrder No,@Basket Id,@Basket Number,@Qu antity,@Ex ecutedQuan tity,@Leav esQuantity ,@OrderTyp e,
@LimitPrice,@AvgFillPrice, @OrderStat us,@StopPr ice,@TimeI nForce,@cn trpartyID, @HostName, @OrderMark ing,@Sourc e )
END
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Historical.', 16,-1)
RETURN
END
IF @@ERROR = 0
BEGIN
COMMIT TRANSACTION
END
END
GO
IF EXISTS(SELECT 1 FROM Database.dbo.Current WHERE tradetime >=@tradetime and ordernumber=@ordernumber)
BEGIN
INSERT Database.dbo.AuditTrail (ActionDate,ActionType,Act
SELECT CURRENT_TIMESTAMP,'Quantit
FROM Database.dbo.Current
WHERE tradeTime >=@tradetime
AND ordernumber = @ordernumber
EXEC SERVER1.Database.dbo.usp_p
EXEC SERVER2.Database.dbo.usp_p
EXEC SERVER3.Database.dbo.usp_p
END
You see, the drivers are coded such that they invoke the editing procedure(s) on the three instances. my people invoke the driver once, it hits all three boxes. i need to do that w/this insert procedure, but i am struggling around all of the defaults. Is anyone able to help me put a driver around this?
That's problem #1. The second issue is a little harder to describe. It may simply not be an option, but I need to check. As you can see, @source defaults to 'FImporter'. Of course, this can be passed in, if needed. I was wondering, IF @source = 'ROLLTRADE', can I go just a step further? If @source=ROLLTRADE, the user also needs to submit a settledate for the trade they just inserted. (@settledate, @ordernumber) I want the gui to do this with as little intervention from the trading desk, as possible. From their point of view, they enter all the information at once, and hit one button to submit. But, IF @source = ROLLTRADE, is there anyway I can then proceed to retrieve the ordernumber (just created) and pass it with @SettleDate to another proc, that will write to another table, without any intervention on the part of the desk?
both are very important, though #2 is a tiny bit more pressing than #1. any suggestions?
CREATE PROCEDURE dbo.insertProc
(
@MsgID varchar(175),
@UserId varchar(16),
@AcctId varchar(16),
@PrevOrderNo varchar(32)='?',
@EndPoint varchar(8),
@Symbol varchar(25),
@BuySell char(1),
@Quantity int,
@Price decimal(18,8),
@TradeTime datetime=NULL,
@ClearingFee int = 0,
@LiquidityFlag char(4)='?',
@Client varchar(32)='MET',
@OrderNumber varchar(100),
@OrigOrderNo varchar(32)='?',
@BasketId char(12)='?',
@BasketNumber varchar(15)='0',
@Quantity bigint=NULL,
@ExecutedQuantity bigint=NULL,
@LeavesQuantity bigint=0,
@OrderType char(1)='L',
@LimitPrice decimal(18,8)=NULL,
@AvgFillPrice decimal(18,8)=NULL,
@OrderStatus varchar(4)='FILL',
@StopPrice decimal(18,8)=0.0,
@TimeInForce varchar(5)='DAY',
@cntrpartyID varchar(15)='?',
@HostName varchar(50)=NULL,
@OrderMarking char(1)=NULL,
@Source varchar(15)='FImporter'
)
AS
SET NOCOUNT ON
BEGIN
--if @tradetime isn't passed, default to today
IF (@TradeTime IS NULL)
SET @TradeTime = GETDATE()
--set these all for defaults
SET @quantity = COALESCE(@quantity, @quantity)
SET @executedquantity = COALESCE(@quantity, @executedquantity)
SET @limitprice = COALESCE(@price,@limitpric
SET @avgfillprice = COALESCE(@price,@avgfillpr
SET @hostname = HOST_NAME()
BEGIN TRANSACTION
IF DATEDIFF(day,@TradeTime,ge
/* if date is current day, insert only into Database.dbo.Current */
BEGIN
INSERT Database.dbo.Current (
[MsgID], [UserId],[AcctId],[PrevOrd
[LiquidityFlag],[Client],[
[LimitPrice],[AvgFillPrice
VALUES (
@MsgId,@UserId,@AcctId,@Pr
@LiquidityFlag,@Client,@Or
@LimitPrice,@AvgFillPrice,
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Current.',16,
RETURN
END
END
ELSE
/* If date within current business week, insert into Database.dbo.Current AND Database.dbo.Historical */
IF DATEDIFF(day,@TradeTime,ge
BEGIN
INSERT Database.dbo.Current (
[MsgID], [UserId],[AcctId],[PrevOrd
[LiquidityFlag],[Client],[
[LimitPrice],[AvgFillPrice
VALUES (
@MsgId,@UserId,@AcctId,@Pr
@LiquidityFlag,@Client,@Or
@AvgFillPrice,@OrderStatus
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Current.',16,
RETURN
END
INSERT Database.dbo.Historical (
[MsgID], [UserId],[AcctId],[PrevOrd
[LiquidityFlag],[Client],[
[LimitPrice],[AvgFillPrice
VALUES (
@MsgId,@UserId,@AcctId,@Pr
@LiquidityFlag,@Client,@Or
@AvgFillPrice,@OrderStatus
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Historical.',
RETURN
END
END
ELSE
/* If date older than current business week, only insert into Database.dbo.Historical.*/
IF DATEDIFF(day,@TradeTime,ge
BEGIN
INSERT Database.dbo.Historical (
[MsgID], [UserId],[AcctId],[PrevOrd
[LiquidityFlag],[Client],[
[LimitPrice],[AvgFillPrice
VALUES (
@MsgId,@UserId,@AcctId,@Pr
@LiquidityFlag,@Client,@Or
@LimitPrice,@AvgFillPrice,
END
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR('Failed to insert into Database.dbo.Historical.',
RETURN
END
IF @@ERROR = 0
BEGIN
COMMIT TRANSACTION
END
END
GO
Why don't you just open 2 sepparate questions?
I am not sure I understand the question with the drivers? You need a sp that fires the inserts on all 3 servers?
Why this:
SET @quantity = COALESCE(@quantity, @quantity)
? id of no good.
SET @quantity = COALESCE(@quantity, @quantity)
? id of no good.
For 2:
Why not just add the settledate as a param defaulted with NULL and then test for the source if ROLLTRADE and use the settledate.
CREATE PROCEDURE dbo.insertProc
(
@MsgID varchar(175),
@UserId varchar(16),
@AcctId varchar(16),
@PrevOrderNo varchar(32)='?',
@EndPoint varchar(8),
@Symbol varchar(25),
@BuySell char(1),
@Quantity int,
@Price decimal(18,8),
@TradeTime datetime=NULL,
@ClearingFee int = 0,
@LiquidityFlag char(4)='?',
@Client varchar(32)='MET',
@OrderNumber varchar(100),
@OrigOrderNo varchar(32)='?',
@BasketId char(12)='?',
@BasketNumber varchar(15)='0',
@Quantity bigint=NULL,
@ExecutedQuantity bigint=NULL,
@LeavesQuantity bigint=0,
@OrderType char(1)='L',
@LimitPrice decimal(18,8)=NULL,
@AvgFillPrice decimal(18,8)=NULL,
@OrderStatus varchar(4)='FILL',
@StopPrice decimal(18,8)=0.0,
@TimeInForce varchar(5)='DAY',
@cntrpartyID varchar(15)='?',
@HostName varchar(50)=NULL,
@OrderMarking char(1)=NULL,
@Source varchar(15)='FImporter',
@settledate datetime=NULL
)
IF @Source='ROLLTRADE' ...
or
CASE @Source
WHEN 'ROLLTRADE' THEN @settledate
ELSE <otherdate_here>
END
Why not just add the settledate as a param defaulted with NULL and then test for the source if ROLLTRADE and use the settledate.
CREATE PROCEDURE dbo.insertProc
(
@MsgID varchar(175),
@UserId varchar(16),
@AcctId varchar(16),
@PrevOrderNo varchar(32)='?',
@EndPoint varchar(8),
@Symbol varchar(25),
@BuySell char(1),
@Quantity int,
@Price decimal(18,8),
@TradeTime datetime=NULL,
@ClearingFee int = 0,
@LiquidityFlag char(4)='?',
@Client varchar(32)='MET',
@OrderNumber varchar(100),
@OrigOrderNo varchar(32)='?',
@BasketId char(12)='?',
@BasketNumber varchar(15)='0',
@Quantity bigint=NULL,
@ExecutedQuantity bigint=NULL,
@LeavesQuantity bigint=0,
@OrderType char(1)='L',
@LimitPrice decimal(18,8)=NULL,
@AvgFillPrice decimal(18,8)=NULL,
@OrderStatus varchar(4)='FILL',
@StopPrice decimal(18,8)=0.0,
@TimeInForce varchar(5)='DAY',
@cntrpartyID varchar(15)='?',
@HostName varchar(50)=NULL,
@OrderMarking char(1)=NULL,
@Source varchar(15)='FImporter',
@settledate datetime=NULL
)
IF @Source='ROLLTRADE' ...
or
CASE @Source
WHEN 'ROLLTRADE' THEN @settledate
ELSE <otherdate_here>
END
ASKER
hi zberteoc. i figured since they were both pertaining to the same proc, i would just open one inquiry. i do hope this wasn't a bad call.
>>You need a sp that fires the inserts on all 3 servers?
Yes, precisely.
I'm not sure I follow you re settledate. See, the need to submit settledate is for the order just inserted. if @source = ROLLTRADE, i need to write the order, then get the ordernumber just inserted, and pass it into another procedure along with the given @settledate
you know what i mean?
>>You need a sp that fires the inserts on all 3 servers?
Yes, precisely.
I'm not sure I follow you re settledate. See, the need to submit settledate is for the order just inserted. if @source = ROLLTRADE, i need to write the order, then get the ordernumber just inserted, and pass it into another procedure along with the given @settledate
you know what i mean?
but you know the @OrderNumber because you passed it into the sp. If the settledate is also passed in the case of ROLLTRADE I don't see what the problem is, ayou already know both values.
ASKER
oh gosh, i'm sorry. no, @ordernumber is autogenerated upon insertion
in this particular case, (the need to manually enter trades) it's not know until the insert occurs
in this particular case, (the need to manually enter trades) it's not know until the insert occurs
how can that be if you have it in the VALUES list in th insert statemens? That means is passed into the sp and it is inserted.
ASKER
sorry, zberteoc, i didn't see your reply until just now.
yes, the proc is written that way, but the @ordernumber itself is autogenerated at the gui -- i believe it actually calls another resource to retrieve the number (an orderid generator)
but this doesn't happen until the insert is executed
yes, the proc is written that way, but the @ordernumber itself is autogenerated at the gui -- i believe it actually calls another resource to retrieve the number (an orderid generator)
but this doesn't happen until the insert is executed
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ok, i'm going to give this a shot, zberteoc. i see what you're saying...
at the end of the proc, should I just
IF @Source='ROLLTRADE' ...
EXEC new proc?
syntactically, how would i do this?
at the end of the proc, should I just
IF @Source='ROLLTRADE' ...
EXEC new proc?
syntactically, how would i do this?
exactly like that
IF @Source='ROLLTRADE'
EXEC spNameHere @ordernumber, @sattledate
nothing else. When the IF condition is true the next sentence is executed. You need BEGIN ... END block only if you have more than one sentences to execute.
IF @Source='ROLLTRADE'
EXEC spNameHere @ordernumber, @sattledate
nothing else. When the IF condition is true the next sentence is executed. You need BEGIN ... END block only if you have more than one sentences to execute.
ASKER
ok, i've done it, zberteoc. exactly as you've suggested
seemingly quite simple, now that i have it in front of me
unfortunately, the testing isn't going to be done until the am. but, i will let you know asap
seemingly quite simple, now that i have it in front of me
unfortunately, the testing isn't going to be done until the am. but, i will let you know asap
ASKER
still unable to get some testing done, zberteoc. i apologize for the delay, but it will happen soon.
ASKER
testing is complete, zberteoc. it went perfectly.
do you have any ideas on the driver?
>>You need a sp that fires the inserts on all 3 servers?
do you have any ideas on the driver?
>>You need a sp that fires the inserts on all 3 servers?
If you need this on 3 different servers at the same time what you'll have to do is to set up linked servers from the main server to the other 2 and then you can simply qualify a table like:
linkedserver.Database.dbo. Current,
where linkedserver is the name you set for the link, may be the same name with the server it links.
After that you need to add an insert statement fora each of these tables:
INSERT INTO database.owner.tablename ... (the one you have_ +
INSERT INTO linkedserver1.database.own er.tablena me ...
and
INSERT INTO linkedserver2.database.own er.tablena me ...
Hpw to set up linked servers you can find here:
http://www.databasejournal.com/features/mssql/article.php/3691721
linkedserver.Database.dbo.
where linkedserver is the name you set for the link, may be the same name with the server it links.
After that you need to add an insert statement fora each of these tables:
INSERT INTO database.owner.tablename ... (the one you have_ +
INSERT INTO linkedserver1.database.own
and
INSERT INTO linkedserver2.database.own
Hpw to set up linked servers you can find here:
http://www.databasejournal.com/features/mssql/article.php/3691721
ASKER
oh yes, i know how to set up the linked servers, and they are already linked. as i said before, i have a number of drivers that exec the procs across all three instances, when called. (see sample below)
i just don't know how to do this insertion across all three..given the number of parms and defaults within
IF EXISTS(SELECT 1 FROM Database.dbo.Current WHERE tradetime >=@tradetime and ordernumber=@ordernumber)
BEGIN
INSERT Database.dbo.AuditTrail (ActionDate,ActionType,Act ionSource, OrderNumbe r,Old,New, UserID,Hos tname)
SELECT CURRENT_TIMESTAMP,'Quantit y',CONVERT (char(20), SERVERPROPERTY('servername ')),@order number,qua ntity,@new qty,SYSTEM _USER,HOST _NAME()
FROM Database.dbo.Current
WHERE tradeTime >=@tradetime
AND ordernumber = @ordernumber
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
END
i just don't know how to do this insertion across all three..given the number of parms and defaults within
IF EXISTS(SELECT 1 FROM Database.dbo.Current WHERE tradetime >=@tradetime and ordernumber=@ordernumber)
BEGIN
INSERT Database.dbo.AuditTrail (ActionDate,ActionType,Act
SELECT CURRENT_TIMESTAMP,'Quantit
FROM Database.dbo.Current
WHERE tradeTime >=@tradetime
AND ordernumber = @ordernumber
EXEC SERVER1.Database.dbo.usp_p
EXEC SERVER2.Database.dbo.usp_p
EXEC SERVER3.Database.dbo.usp_p
END
Yes, if you created the sp on all 3 servers than it should work. I thaught that you needed to do the inserts on 3 different servers.
What I understand from your code is that if you have 1 "main" server where you execute the insert stored procedure from where you call the second sp on other 3 servers. Is that right?
What I understand from your code is that if you have 1 "main" server where you execute the insert stored procedure from where you call the second sp on other 3 servers. Is that right?
ASKER
not really. i've got three instances, they are to be identical at all times. there isn't really a primary or secondary, they're supposed to be the same. they're all written to in parallel, but when data revisions are required, i have to push them to all three boxes. the same proc would exist on all three instances, and they are executed by drivers, which also exist on all three instances. thus, it doesn't matter where they're connected. if/when the driver is invoked, it will impact all three machines.
I'm not sure I understand what you mean by driver.
You'll have a problem with this setup because I don't think you can create a linked server to itself (this is what I understood, no matter where you are you execute the 3 calls: EXEC SERVERn) , that means if you executed the calling proc on SERVER1, the EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
will give you error.
If it doesn't work you'll have to use a dynamic query like this:
DECLARE
@sql nvarchar(1000)
SELECT
@sql=
CASE @@SERVERNAME
WHEN 'SERVER1' THEN
'
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
'
END
IF @sql IS NOT NULL
EXEC sp_sqlexec @sql
You'll have a problem with this setup because I don't think you can create a linked server to itself (this is what I understood, no matter where you are you execute the 3 calls: EXEC SERVERn) , that means if you executed the calling proc on SERVER1, the EXEC SERVER1.Database.dbo.usp_p
will give you error.
If it doesn't work you'll have to use a dynamic query like this:
DECLARE
@sql nvarchar(1000)
SELECT
@sql=
CASE @@SERVERNAME
WHEN 'SERVER1' THEN
'
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p
EXEC SERVER3.Database.dbo.usp_p
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p
EXEC SERVER2.Database.dbo.usp_p
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
'
END
IF @sql IS NOT NULL
EXEC sp_sqlexec @sql
Sorry, the third one should have been:
WHEN 'SERVER3' THEN
WHEN 'SERVER3' THEN
actually I forgot about params, the correct code is this:
DECLARE
@sql nvarchar(1000)
@params nvarchar(1000)
SELECT
@sql=
CASE @@SERVERNAME
WHEN 'SERVER1' THEN
'
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
'
WHEN 'SERVER3' THEN
'
EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
'
END
@params='@newqty typehere, @ordernumber typehere, @tradetime datetime'
IF @sql IS NOT NULL
EXEC sp_sqlexec @sql, @params, @newqty, @ordernumber, @tradetime
DECLARE
@sql nvarchar(1000)
@params nvarchar(1000)
SELECT
@sql=
CASE @@SERVERNAME
WHEN 'SERVER1' THEN
'
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER2.Database.dbo.usp_p
EXEC SERVER3.Database.dbo.usp_p
'
WHEN 'SERVER2' THEN
'
EXEC SERVER1.Database.dbo.usp_p
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
EXEC SERVER3.Database.dbo.usp_p
'
WHEN 'SERVER3' THEN
'
EXEC SERVER1.Database.dbo.usp_p
EXEC SERVER2.Database.dbo.usp_p
EXEC Database.dbo.usp_procName @newqty, @ordernumber, @tradetime
'
END
@params='@newqty typehere, @ordernumber typehere, @tradetime datetime'
IF @sql IS NOT NULL
EXEC sp_sqlexec @sql, @params, @newqty, @ordernumber, @tradetime
ASKER
oh, you know, i hadn't thought about that. i guess because there are some 30 odd parms in the insert proc, i wasn't thinking i could/should do that dynamically.
>> that means if you executed the calling proc on SERVER1, the EXEC SERVER1.Database.dbo.usp_p rocName @newqty, @ordernumber, @tradetime
will give you error.
and this puzzles me. how is it that you expect that to error? the drivers are called once w/all the parms. then, within the driver, the proc(s) are executed on each of the machines, just like this:
exec server1 database.dbo.insertproc @parm1, @parm2, @parm3.....
exec server2 database.dbo.insertproc @parm1, @parm2, @parm3.....
exec server3 database.dbo.insertproc @parm1, @parm2, @parm3.....
that's done within the drivers. at least the ones that are working already. i wasn't sure that was the right way to do the one with so many parms
>> that means if you executed the calling proc on SERVER1, the EXEC SERVER1.Database.dbo.usp_p
will give you error.
and this puzzles me. how is it that you expect that to error? the drivers are called once w/all the parms. then, within the driver, the proc(s) are executed on each of the machines, just like this:
exec server1 database.dbo.insertproc @parm1, @parm2, @parm3.....
exec server2 database.dbo.insertproc @parm1, @parm2, @parm3.....
exec server3 database.dbo.insertproc @parm1, @parm2, @parm3.....
that's done within the drivers. at least the ones that are working already. i wasn't sure that was the right way to do the one with so many parms
ASKER
if the insert proc exists on all three instances, could i not just do the driver like the others? kinda like this:
exec server1 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
exec server2 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
exec server3 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
that would be preferred, over the dynamic, as i don't want the enduser to have to pass in a servername, nor do i really feel good about the risks of the dynamic tSQL. (though i am using it in some places, i just don't want to do more, if i can avoid it)
exec server1 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
exec server2 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
exec server3 database.dbo.insertproc @parm1, @parm2, @parm3..... @parm30
that would be preferred, over the dynamic, as i don't want the enduser to have to pass in a servername, nor do i really feel good about the risks of the dynamic tSQL. (though i am using it in some places, i just don't want to do more, if i can avoid it)
Sorry, my bad, you actually can qualify a table starting with the server name.I learned something today. :) So it will be fine with the condition that any given server will be linked with the other 2.
Ooops, aparently works with tables but not with stored procedures.
Sorry, again, I'm confused now, it should work with sps as well. Just try it ands tell me if it worked.
ASKER
i'm trying it now, i will let you know as soon as i know something more
ASKER
Yep, it worked just fine. Just like all of my other drivers. I don't know if it was just all the parms, or something else entirely that tripped me up... but, it works perfectly.
Thanks very much for your assitance, Zdberteoc. I do appreciate the help w/ROLLTRADE, and the push to figure out my driver.
Thanks very much for your assitance, Zdberteoc. I do appreciate the help w/ROLLTRADE, and the push to figure out my driver.
ASKER
sorry for the misspelling. of course, i meant 'Zberteoc'
again, thanks very much
again, thanks very much
Glad I could be of help, cheers!