设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 6299|回复: 7
打印 上一主题 下一主题

[原创]利用触发器实现即时更新表记录!

[复制链接]
跳转到指定楼层
1#
发表于 2005-12-7 05:24:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
【已知条件】
“存入” “客户” 两表

“存入”表—字段如下:
       存入账户ID
       人员编号(外部键)
       存入金额
“客户”表—字段如下
       人员编号(主键)
       姓名
      性别
      账户余额


在“存入”表中制有如下触发器
  CREATE TRIGGER km_ZFQ ON [dbo].[存入]
  FOR INSERT, UPDATE, DELETE
  AS
  UPDATE  客户
  SET  客户.账户余额 = (SELECT SUM(存入金额) FROM 存入 WHERE 存入.人员编号=客户.人员编号)
  FROM 客户,存入
  WHERE 客户.人员编号=存入.人员编号;


【目的】
 当对“存入”表进行插入、修改、删除操作时“客户”表中的〔帐户余额〕始终保持最新。实现了即时更新的目的。

【问题】
  虽然上述的触发器实现了“客户”表帐户余额的即时更新,但我觉得该触发器如果处理数万以上的数据可能速度会大大降底!!(因为“WHERE 客户.人员编号=存入.人员编号”,是对所有记录进行批量更新。

  要是上述触发器按“存入”表中当前操作(修改、插入、删除)记录的〔人员编号〕进行更新是必甚好。

  我在想能不能把上述“WHERE 客户.人员编号=存入.人员编号”中的“存入.人员编号”用某中方法得到“存入”表当前记录的“人员编号”值(即“WHERE 客户.人员编号={存入表当前记录人员编号}”)。

望路过高手略指一二。(我正在对SQL语句学习中)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
发表于 2005-12-7 17:56:00 | 只看该作者
那得先判断正在处理的是唯一一条记录。

我的做法是分开写三种触发器,可以在其它地方做个东西判断“帐户余额”对不对。
3#
发表于 2005-12-7 20:54:00 | 只看该作者
WHERE 客户.人员编号=inserted.人员编号

触发器可以生成deleted和inserted两个临时表。deleted存放更新前当前影响的记录。inserted存放当前更新后的记录。
4#
 楼主| 发表于 2005-12-10 06:49:00 | 只看该作者
是利用deleted和inserted两个临时表,来获得当前操作记录的ID号。是吗?
5#
发表于 2005-12-17 00:13:00 | 只看该作者
这里有个触发器的例子 ,,看看您能看懂不?

Alter TRIGGER GOODSINITTRIGGER1 ON GOODSINIT INSTEAD OF UPDATE AS
DECLARE @CurrYear INT, @CurrMonth INT
DECLARE @NEW_GOODSID T_KEYID, @NEW_YEARNUM T_KEYID_S, @NEW_MONTHNUM T_KEYID_S, @NEW_BQTY T_QUANTITY, @NEW_BPRICE T_PRICE, @NEW_INQTY
T_QUANTITY, @NEW_OUTQTY T_QUANTITY, @NEW_EQTY T_QUANTITY, @NEW_EPRICE T_PRICE, @NEW_BAMOUNT T_AMOUNT, @NEW_EAMOUNT T_AMOUNT
DECLARE @OLD_GOODSID T_KEYID, @OLD_YEARNUM T_KEYID_S, @OLD_MONTHNUM T_KEYID_S, @OLD_BQTY T_QUANTITY, @OLD_BPRICE T_PRICE, @OLD_INQTY
T_QUANTITY, @OLD_OUTQTY T_QUANTITY, @OLD_EQTY T_QUANTITY, @OLD_EPRICE T_PRICE, @OLD_BAMOUNT T_AMOUNT, @OLD_EAMOUNT T_AMOUNT
DECLARE NEWED CURSOR LOCAL FORWARD_ONLY STATIC OPTIMISTIC FOR SELECT GOODSID, YEARNUM, MONTHNUM, BQTY, BPRICE, INQTY, OUTQTY,
EQTY, EPRICE, BAMOUNT, EAMOUNT FROM INSERTED Order By GOODSID,YearNum,MonthNum
DECLARE OLDED CURSOR LOCAL FORWARD_ONLY STATIC OPTIMISTIC FOR SELECT GOODSID, YEARNUM, MONTHNUm, BQTY, BPRICE, INQTY, OUTQTY,
EQTY, EPRICE, BAMOUNT, EAMOUNT FROM DELETED Order By GOODSID,YearNum,MonthNum
OPEN NEWED
OPEN OLDED
FETCH NEXT FROM NEWED INTO @NEW_GOODSID, @NEW_YEARNUM, @NEW_MONTHNUM, @NEW_BQTY, @NEW_BPRICE, @NEW_INQTY, @NEW_OUTQTY, @NEW_EQTY,
@NEW_EPRICE, @NEW_BAMOUNT, @NEW_EAMOUNT
IF (@@FETCH_STATUS = 0)
  FETCH NEXT FROM OLDED INTO @OLD_GOODSID, @OLD_YEARNUM, @OLD_MONTHNUM, @OLD_BQTY, @OLD_BPRICE, @OLD_INQTY, @OLD_OUTQTY ,@OLD_EQTY, @OLD_EPRICE, @OLD_BAMOUNT, @OLD_EAMOUNT
WHILE (@@FETCH_STATUS = 0)
  BEGIN
    --BEGIN TRANSACTION
    SET @NEW_EQTY = @NEW_BQTY + @NEW_INQTY - @NEW_OUTQTY
    IF (@NEW_BQTY <> @OLD_BQTY OR @NEW_BPRICE <> @OLD_BPRICE)
      SET @NEW_BAMOUNT = @NEW_BQTY * @NEW_BPRICE
    IF (- 0.0000001 < @NEW_EQTY AND @NEW_EQTY < 0.0000001)
      SET @NEW_EQTY = 0
    IF (@NEW_EAMOUNT = @OLD_EAMOUNT AND @NEW_BAMOUNT <> @OLD_BAMOUNT)
      SET @NEW_EAMOUNT = @OLD_EAMOUNT + @NEW_BAMOUNT - @OLD_BAMOUNT
    IF (@NEW_BQTY <> @OLD_BQTY OR @NEW_BPRICE <> @OLD_BPRICE)
    BEGIN
        SELECT @CURRYEAR = POSYEAR, @CURRMONTH = POSMON FROM ACCINFO
        UPDATE DETAILBILLFLOW SET CACULATEFLAG = 'F' WHERE BILLDATE >= CAST (convert (varchar,@CURRMONTH) + '/01/' + convert (varchar,@CURRYEAR) AS DATETIME) AND                  GOODSID = @OLD_GOODSID
    END
    UPDATE GOODSINIT SET GOODSID = @NEW_GOODSID, YEARNUM = @NEW_YEARNUM, MONTHNUM = @NEW_MONTHNUM, BQTY = @NEW_BQTY, BPRICE =                                                  @NEW_BPRICE, INQTY = @NEW_INQTY, OUTQTY = @NEW_OUTQTY, EQTY = @NEW_EQTY, EPRICE = @NEW_EPRICE, BAMOUNT = @NEW_BAMOUNT,
                                                 EAMOUNT =   @NEW_EAMOUNT
     WHERE GOODSINIT.GOODSID = @OLD_GOODSID AND GOODSINIT.YEARNUM = @OLD_YEARNUM AND GOODSINIT.MONTHNUM = @OLD_MONTHNUM

     FETCH NEXT FROM NEWED INTO @NEW_GOODSID, @NEW_YEARNUM, @NEW_MONTHNUM, @NEW_BQTY, @NEW_BPRICE, @NEW_INQTY, @NEW_OUTQTY,                                                                @NEW_EQTY, @NEW_EPRICE, @NEW_BAMOUNT, @NEW_EAMOUNT
     IF (@@FETCH_STATUS = 0)
             FETCH NEXT FROM OLDED INTO @OLD_GOODSID, @OLD_YEARNUM, @OLD_MONTHNUM, @OLD_BQTY, @OLD_BPRICE, @OLD_INQTY, @OLD_OUTQTY,                                                                        @OLD_EQTY, @OLD_EPRICE, @OLD_BAMOUNT, @OLD_EAMOUNT
    END
    CLOSE NEWED
    DEALLOCATE NEWED
    CLOSE OLDED
    DEALLOCATE OLDED




---以上代码中T_KEYID_S  ,T_QUANTITY 等是自定义数据类型

[此贴子已经被作者于2005-12-16 16:14:58编辑过]

6#
发表于 2006-1-15 05:37:00 | 只看该作者
what
7#
发表于 2012-4-22 18:43:45 | 只看该作者
好复杂的程序,看不懂
8#
发表于 2013-3-28 16:00:13 | 只看该作者
{:soso_e115:}黑麻麻一片
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-3 21:16 , Processed in 0.086537 second(s), 31 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表