求大神解惑,关于触发器多表关联判断

Najd 2017-09-24 12:49:20
假如现在有三个个表,分别是
Stock:库存单据表(表头)
StockEntry:库存单据表(表体)
Item:商品表

Stock[库存单据表头]是出入库单据的表头,有以下字段
BillNo:单据内码(唯一)
其他信息(略)

[b]StockEntry[库存单据表体]
是用出入库信息的表体,有以下字段,表头与表体之间用BillNo关联
BillNo:单据内码(唯一)
ItemID:商品内码
Length:商品长度
Height:商品高度
Weight:商品重量[/b]

Item[商品表]表示用来存储商品的基础信息的,有以下字段
ItemID:商品内码(唯一)
ItemNumber:商品代码
ItemName:商品名称

其中Stock表里面的商品长度是根据公式来计算的,计算公式为:长度=重量/5/高度
但是又不是所有的商品都是需要长度这一数值,只有少数商品需要计算长度

比如说,现在有两个商品:钢管,卷板
其中 卷板 是需要计算长度的,但是钢管是不需要的

现在就是想写一个触发器,当库存单据表里面录入有关于 卷板 的信息的时候就自动计算长度,如果录入的是钢管或者其他商品就不执行操作

但是有一个问题就是 商品的内码和代码都不是固定的,只有名称里面一定会出现譬如“XX卷板XX”/“XX钢管XX”等信息,但是库存单据体里面又不是直接用商品名称来存储商品信息。

所以就想用多表关联,利用关联Item表上的商品名称来判断触发这个公式
触发器语句如下:


Create Trigger Test
On Stock
For Update,Insert
As
Declare @TBillNo int,@Name nvarchar
set @Name=(Select Name from Item a inner join Stock b on a.ItemID=b.ItemID)
if (@Name like '%卷板%')
begin
select @TBillNo=BillNo from inserted
update StockEntry SET Length=Weight/5/Height
where @TBillNo=BillNo
end

结果很惨。。。效率很差而且Select返回的是单据体所有行的商品名称,根本用不了。

所以想请教各位大神有办法让这个触发器逐行触发吗,或者有没有别的方式能够实现我的这一需求,望大神们指点一二,感激不尽

...全文
326 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
中国风 2017-09-25
  • 打赏
  • 举报
回复
ItemID是在表体(StockEntry ),还是在表头(Stock),以下以表体为例 你的判断条件,没有引用逻辑表INSERTED,用以下方法测测 e.g.
CREATE TRIGGER Test ON Stock
    FOR UPDATE, INSERT
AS
SET NOCOUNT ON;
UPDATE b
SET Length = Weight / 5 / Height
FROM    inserted AS a
        INNER JOIN StockEntry AS b ON b.BillNo = a.BillNo
		INNER JOIN Item AS c WITH(NOLOCK) ON c.ItemID=b.ItemID
WHERE c.Name LIKE '%卷板%';
二月十六 版主 2017-09-24
  • 打赏
  • 举报
回复
试试这个:
CREATE TRIGGER Test ON StockEntry  --这里应该是StockEntry吧?
    FOR UPDATE, INSERT
AS
    IF ( EXISTS ( SELECT    Name
                  FROM      Item a
                            INNER JOIN inserted b ON a.ItemID = b.ItemID
                  WHERE     Name LIKE '%卷板%' ) )
        BEGIN
            
            UPDATE  StockEntry
            SET     Length = Weight / 5 / Height
            WHERE   BillNo IN ( SELECT  BillNo
                                FROM    inserted
                                WHERE   Name LIKE '%卷板%' );
        END;
听雨停了 2017-09-24
  • 打赏
  • 举报
回复
引用 2 楼 Atonei的回复:
[quote=引用 1 楼 qq_37170555 的回复:]

Create Trigger Test
On Stock
For Update,Insert
As
Declare @TBillNo int,@Name nvarchar
set @Name=(Select Name from Item a 
inner JOIN StockEntry b ON a.itemid=b.itemid 
inner join inserted c on c.BillNo=b.BillNo)
if (@Name like '%卷板%')
begin
select @TBillNo=BillNo  from inserted
update StockEntry SET Length=Weight/5/Height
where @TBillNo=BillNo
end
这样就可以了,我看你的问题,你直接Select Name from Item a inner join Stock b on a.ItemID=b.ItemID;这两个表好像关联不到一起吧,表一都没有itemID的啊,所以我上面用了三个表关联。是不是我搞错了啊。不管怎么样,你试试上面这样行不行
我主题里面写错了,刚试了一下还是不行啊[/quote] 如果是的话那你的表2首先得有对应的数据,就是你得先插数据到表2,然后再插入到表1,这时候触发器就会触发,然后去修改对应表2的数据
听雨停了 2017-09-24
  • 打赏
  • 举报
回复
引用 2 楼 Atonei的回复:
[quote=引用 1 楼 qq_37170555 的回复:]

Create Trigger Test
On Stock
For Update,Insert
As
Declare @TBillNo int,@Name nvarchar
set @Name=(Select Name from Item a 
inner JOIN StockEntry b ON a.itemid=b.itemid 
inner join inserted c on c.BillNo=b.BillNo)
if (@Name like '%卷板%')
begin
select @TBillNo=BillNo  from inserted
update StockEntry SET Length=Weight/5/Height
where @TBillNo=BillNo
end
这样就可以了,我看你的问题,你直接Select Name from Item a inner join Stock b on a.ItemID=b.ItemID;这两个表好像关联不到一起吧,表一都没有itemID的啊,所以我上面用了三个表关联。是不是我搞错了啊。不管怎么样,你试试上面这样行不行
我主题里面写错了,刚试了一下还是不行啊[/quote] 你要做的是当表1插入数据的时候,更新表2里面的相对应的billid的长度是吗
Najd 2017-09-24
  • 打赏
  • 举报
回复
引用 1 楼 qq_37170555 的回复:

Create Trigger Test
On Stock
For Update,Insert
As
Declare @TBillNo int,@Name nvarchar
set @Name=(Select Name from Item a 
inner JOIN StockEntry b ON a.itemid=b.itemid 
inner join inserted c on c.BillNo=b.BillNo)
if (@Name like '%卷板%')
begin
select @TBillNo=BillNo  from inserted
update StockEntry SET Length=Weight/5/Height
where @TBillNo=BillNo
end
这样就可以了,我看你的问题,你直接Select Name from Item a inner join Stock b on a.ItemID=b.ItemID;这两个表好像关联不到一起吧,表一都没有itemID的啊,所以我上面用了三个表关联。是不是我搞错了啊。不管怎么样,你试试上面这样行不行
我主题里面写错了,刚试了一下还是不行啊
听雨停了 2017-09-24
  • 打赏
  • 举报
回复

Create Trigger Test
On Stock
For Update,Insert
As
Declare @TBillNo int,@Name nvarchar
set @Name=(Select Name from Item a 
inner JOIN StockEntry b ON a.itemid=b.itemid 
inner join inserted c on c.BillNo=b.BillNo)
if (@Name like '%卷板%')
begin
select @TBillNo=BillNo  from inserted
update StockEntry SET Length=Weight/5/Height
where @TBillNo=BillNo
end
这样就可以了,我看你的问题,你直接Select Name from Item a inner join Stock b on a.ItemID=b.ItemID;这两个表好像关联不到一起吧,表一都没有itemID的啊,所以我上面用了三个表关联。是不是我搞错了啊。不管怎么样,你试试上面这样行不行

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧