【问题标题】:How to create multirow after insert trigger sql插入触发器sql后如何创建多行
【发布时间】:2018-09-01 06:21:48
【问题描述】:

我为单行插入创建了一个触发器,但它不适用于多行插入。

这是我的桌子:

create table tb_pengiriman
(
    id_pengiriman char(5) not null primary key
        constraint cek_id_pengiriman check (id_pengiriman like('PE[0-9][0-9][0-9]')),
    provinsi varchar(30) not null,
    kota varchar(30) not null,
    harga_ongkir bigint null
        constraint cek_harga_ongkir check (harga_ongkir >-1)
);

alter table tb_pengiriman add
    constraint cek_kota_banten 
    check ((provinsi = 'Banten') and (kota in ('Tangerang','Serang','Cilegon','Tangerang Selatan'))),

这里是触发器:

create trigger tr_pengiriman
on tb_pengiriman
after insert
as
    begin

        declare @id_pengiriman char(5), 
                @provinsi varchar(30), 
                @kota varchar(30);

        select @id_pengiriman = id_pengiriman from inserted;
        select @provinsi = provinsi from inserted;
        select @kota = kota from inserted;
        exec sp_pengiriman @id_pengiriman,@provinsi,@kota;

    end
    go

    create procedure sp_pengiriman
    @id_pengiriman char(5), 
    @provinsi varchar(30), 
    @kota varchar(30)
    As
    Begin
        --proses kalkulasi ongkos kirim
        if(@kota = 'Tangerang')
        begin
            update tb_pengiriman 
            set harga_ongkir = 20000 
            where id_pengiriman = @id_pengiriman
        end
        else if(@kota = 'Serang')
        begin
            update tb_pengiriman 
            set harga_ongkir = 50000 
            where id_pengiriman = @id_pengiriman
        end
        else if(@kota = 'Tangerang Selatan')
        begin
            update tb_pengiriman 
            set harga_ongkir = 15000 
            where id_pengiriman = @id_pengiriman
        end
        else if(@kota = 'Cilegon')
        begin
            update tb_pengiriman 
            set harga_ongkir = 30000 
            where id_pengiriman = @id_pengiriman
        end
        else 
        begin
            rollback transaction
            print 'kota tidak terdaftar'
        end
    end
    go

此代码适用于单行插入,但是当我尝试执行多行插入时,所有行都更改为相同的触发器过程更新查询。

如何使此查询适用于多行插入和单行插入?

【问题讨论】:

  • 恕我直言,您应该尝试使用 CURSOR。
  • 您的开始交易在哪里?
  • 这里有几件事很糟糕。首先是您的程序正在回滚未开始的事务。仅此一项就有好几层不好。您永远不应该在触发器中进行回滚或提交。如果您的调用代码正在使用交易,您很可能会破坏它。您的过程中也有 sp_ 前缀。这不是一个好主意。 sqlperformance.com/2012/10/t-sql-queries/sp_prefix 但实际上你甚至不需要那个程序。它可以是单个更新语句。你为什么要更新你刚刚插入的行?

标签: sql sql-server triggers procedure


【解决方案1】:

您可以仅使用计算列将其简化大约 1000%。这里根本不需要触发器。您的约束强制 kota 的值仅是这四个值之一。这应该可以完成您正在尝试执行的操作,而无需任何触发器等。

create table tb_pengiriman
(
    id_pengiriman char(5) not null primary key
        constraint cek_id_pengiriman check (id_pengiriman like('PE[0-9][0-9][0-9]')),
    provinsi varchar(30) not null,
    kota varchar(30) not null,
    harga_ongkir as case kota when 'Tangerang' then 20000 
                        when 'Serang' then 50000
                        when 'Tangerang Selatan' then 15000
                        when 'Cilegon' then 30000
                        end persisted
        constraint cek_harga_ongkir check (harga_ongkir >-1)
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多