0

我被告知要为我们的 SQL Server 2000 上的插入创建触发器。

我以前从未编写过触发器,而且我们的旧服务器似乎没有定义任何触发器。

在 SQL Server教程中的触发器之后,我创建了这个尚未执行的触发器:

create trigger trgAfterMachine1Insert on Test_Results
after insert
as
  declare @sn varchar(20), @sysID varchar(50),
          @opID varchar(50), @testResult varchar(255)
  select @sn=Serial_Number from inserted
  select @sysID=System_ID from inserted
  select @opID=Op_ID from inserted
  select @testResult=Test_Result from inserted

  exec sp1_AddSnRecord(@sn, @sysID, @opID, @testResult)

  print 'Machine1 After Insert Trigger called AddSnRecord'

go

首先,请注意我已经编写了一个存储过程,调用该存储过程sp1_AddSnRecord将这些数据插入到一个新表中(所以我不会弄乱现有的表)。我当然希望可以在触发器上调用存储过程,因为它在将任何内容插入其他表之前对数据执行数据验证和枚举。

我真的看不到在 SQL Server 2000 中测试这是否可行的方法,而且我对在 Management Studio 中点击执行按钮有点紧张。

所以,我已经研究了一段时间,并尝试阅读其他一些 SO 技术。

Aaron Bertrand的示例HERE看来,我可以将所有选择调用合并到一行中:

create trigger trgAfterMachine1Insert on Test_Results
after insert

as

  declare @sn varchar(20), @sysID varchar(50),
          @opID varchar(50), @testResult varchar(255)

  select @sn=Serial_Number, @sysID=System_ID,
         @opID=Op_ID, @testResult=Test_Result 
  from inserted

  exec sp1_AddSnRecord(@sn, @sysID, @opID, @testResult)

  print 'Machine1 After Insert Trigger called AddSnRecord'

go

否则,我在任何地方都看不到任何更有启发性的东西,或者看到有人询问在创建触发器之前测试触发器的技术。

我在这里工作的一所大学做的 SQL 工作比我多,但他承认他从未编写过触发器。他只能告诉我,“伙计,如果你搞砸了,你可能会在服务器上造成很多问题!” 所做的只是让我紧张,这就是我在这里的原因。(我所做的 98% 是为 Windows 窗体和旧的 Windows Mobile 设备编写 C# 代码)。

那么,我将如何验证此触发器是否有效并且在创建之前不会在服务器上引起任何问题?我的机器上有一个本地 SQL Server Express,但它比 SQL 2000 更新得多,并且没有从我们的生产车间运行的实时数据。

如果事后证明触发器有故障,我可以用简单的方法将其移除delete trigger trgAfterMachine1Insert吗?我对“删除触发器”的搜索似乎主要返回了AFTER DELETE.

提前致谢。

更新:包括马丁要求的存储过程:

ALTER PROCEDURE [dbo].[sp1_AddSnRecord](
    @serial_Number varchar(20), 
    @system_ID varchar(50), 
    @op_ID varchar(50), 
    @test_Result varchar(255)) as begin
  set NOCOUNT ON;
  declare @sn as VarChar(20);
  set @sn=dbo.fn_ValidSN(@serial_Number);
  if (7<Len(@sn)) begin
    declare @badge varchar(50), @result varchar(50), @sysID varchar(50);
    set @badge=dbo.fn_GetBadge(@op_ID);
    set @result=dbo.fn_GetTestResult(@test_Result);
    set @sysID=dbo.fn_GetSysType(@system_ID);
    if ((0<Len(@badge)) and (0<Len(@result)) and (0<Len(@sysID))) begin
      declare @id int;
      select @id=ID from Serial_Numbers where Serial_Number=@sn;
      if (@id<1) begin -- this serial number has not been entered
        insert into Serial_Numbers (Serial_Number) values (@sn);
        select @id=@@IDENTITY from Serial_Numbers;
      end
      if (0<@id) begin -- now insert into SN_Records
        insert into SN_Records (SN_ID, SYS_ID, OP_ID, Date_Time, Test_Result)
          values (@id, @sysID, @badge, GetDate(), @result);
      end
    end
  end
end
4

1 回答 1

4

所以,让我重新表述你所说的:

  • 你没有编写触发器的经验
  • 公司里没有其他人有编写触发器的经验
  • 你只有一个生产环境,没有其他地方可以测试你的代码
  • 管理层告诉你今晚之前完成这项工作

这肯定是灾难的秘诀。

首先,您需要反对您唯一选择失败的请求。告诉管理层他们的数据太重要了,如果没有适当的测试就不能做这样的事情。

然后得到一个合适的测试环境。如果您的公司是 MSDN 订阅者,您将可以访问 SQL Server 2000 Developer Edition 的副本,您可以将其安装在笔记本电脑上,或者更好地安装在某些虚拟机中。

在等待安装时,请阅读有关软件开发中的专业行为的信息。从http://en.wikipedia.org/wiki/Robert_Cecil_Martin开始,然后转到软件工艺。


但是,我知道今晚不会发生这种情况,您可以在此期间执行此操作:

1)在生产服务器上新建数据库

2)复制有问题的表:SELECT TOP(10) * INTO NewDb.dbo.Table FROM OldDb.dbo.Table; 您不需要更多数据,因为这是一个插入触发器

3)以相同的方式复制您需要的其他表

4) 将触发器应用于 NewDb 中的表

5) 测试

6)修复并返回5

7)如果您满意,将触发器复制到OldDb

需要考虑的一些事项:

  • 确保您测试多于一行的插入
  • 不要在触发器中调用过程。并不是说这本身就是错误的,但是您将无法使用它进行多行插入
  • 永远不要使用@@IDENTITY。那是命令。(原因和解决方法在这里:http ://sqlity.net/en/351/identity-crisis/ )

毕竟,这里开始研究数据库中的 TDD:tSQLt.org (大多数想法在 SQL 2000 中有效,但框架却没有。)

希望有帮助。

于 2013-01-08T19:36:11.100 回答