【问题标题】:What is a better way to write this SQL Stored Procedure?编写此 SQL 存储过程的更好方法是什么?
【发布时间】:2011-04-12 23:48:48
【问题描述】:

我正在使用 SQL 存储过程更新交易交易日志,并且我正在使用相同的存储过程同时更新当前订单表。

因为我遇到了一个严重的问题,即 Log 表没有更新而 Current Order 表做了...我在底部添加了一个(第 3 个)例程,用于检查 Log Table 是否已更新引用 ID(ClientID ),如果错误表中不存在则输入错误。

我在问...这个 sproc 写得有多糟糕?帮助或建议表示赞赏。

ALTER PROCEDURE dbo.sprocVT4_addTradeLong
@seqno varchar(35) = NULL,
@exctyp varchar(35) = NULL,
@ordstat varchar(35) = NULL,
@clid varchar(35) = NULL,
@exid varchar(35) = NULL,
@type varchar(35) = NULL,
@side varchar(35) = NULL,
@exch varchar(35) = NULL,
@sym varchar(35) = NULL,
@lstqty varchar(35) = NULL,
@lstpri varchar(35) = NULL,
@text varchar(35) = NULL,
@cumqty varchar(35) = NULL,
@lftqty varchar(35) = NULL,
@now varchar(35) = NULL
AS
BEGIN
-- NO EXISTS ------------
Declare @RC int

SELECT [Symbol] FROM TradesLongForex T WHERE T.ExecId = @exid

SELECT @RC = @@ROWCOUNT
IF @RC <= 0

INSERT INTO TradesLongForex ([SeqNo], [ExecType], [Status], [ClientId], [ExecId], [Type], [Side], [Exchange], [Symbol], [LastQty], [LastPrice], [Text], [CummQty], [LeftQty], [Date])

VALUES (@seqno, @exctyp, @ordstat, @clid, @exid, @type, @side, @exch, @sym, @lstqty, @lstpri, @text, @cumqty, @lftqty, @now)

UPDATE OrdersIdHoldForex SET [OrdExcType] = @exctyp, [OrdStatus] = @ordstat, [OrdType] = @type, [OrdSide] = @side, [OrdPrice] = @lstpri, [OrdQty] = @cumqty, [OrdRemain] = @lftqty

WHERE [Ticker] = @sym

DECLARE @RC2 int

SELECT @RC2 = @@ROWCOUNT

SELECT [ClientId] FROM TradesLongForex WHERE [ClientId] = @clid
if @RC2 <=0

INSERT INTO ERRLOG ([Date], [Message])

VALUES (GETDATE(), 'ERROR INSERTING TRADESLONGFOREX CLID = ' + CONVERT(varchar(10),@CLID))

END

【问题讨论】:

  • 如果没有进一步的背景描述您正在尝试做什么,很难就如何改进提出建议。仅查看您发布的内容,尽管看起来很简单,可以保持原样。
  • 谢谢。 @ajdams,这很有帮助。

标签: sql sql-server-2005 stored-procedures


【解决方案1】:

Phil 对交易提出了很好的观点。这个概念被称为“原子性”,基本上意味着每个事务/进程都是原子的和自包含的。

SQL Server 中事务的一般语法类似于:

BEGIN TRY
BEGIN TRANSACTION
...

your code here

...

COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 1 ROLLBACK

... error reporting code ...

END CATCH

这里的要点是,使用TRY/CATCH 块来捕获错误,并且只有在您顺利通过整个TRY 块时才提交事务。任何错误都会将您发送到CATCH 块,该块会回滚打开的事务。

Here's a primer on error handling.

【讨论】:

    【解决方案2】:

    我不能 100% 确定您在问什么,但您似乎需要阅读一些有关数据库事务的信息。本质上,您可以将一组查询包装在一个事务中,它将确保所有操作都已完成,或者它们都没有完成。所以如果发生错误,整个操作都会回滚。

    http://en.wikipedia.org/wiki/Database_transaction

    【讨论】:

    • 在更高的级别,也许但是这个sproc正在记录已完成的事件,所以无论如何我都需要知道它。
    猜你喜欢
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2011-05-11
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    相关资源
    最近更新 更多