简体   繁体   English

验证新的SQL Server 2000创建触发器

[英]Validate new Create Trigger for SQL Server 2000

I have been told to create a trigger for inserts on our SQL Server 2000. 有人告诉我在SQL Server 2000上为插入创建触发器。

I've never written a trigger before, and our old server does not appear to have any triggers defined on it. 我以前从未编写过触发器,并且我们的旧服务器似乎没有在其上定义任何触发器。

Following the Triggers in SQL Server tutorial, I have created this trigger that I have not executed yet: 在《 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

First, notice that I have written a stored procedure called sp1_AddSnRecord to insert this data into a new table (so I do not mess up the existing table). 首先,请注意,我编写了一个名为sp1_AddSnRecord的存储过程,以将该数据插入到新表中(因此,我不会弄乱现有表)。 I certainly hope a stored procedure can be called on a trigger, because it performs data validation and enumeration on the data before inserting anything into the other tables. 我当然希望可以在触发器上调用存储过程,因为它会在将数据插入其他表之前对数据执行数据验证和枚举。

I really don't see a way in SQL Server 2000 to test to see if this will work, and I'm a bit nervous about just hitting that Execute button in Management Studio. 我真的没有在SQL Server 2000中看到一种方法来测试它是否可以工作,并且我对仅单击Management Studio中的“ 执行”按钮感到有些紧张。

So, I've been looking at this for a while and trying to read up on some other SO techniques. 因此,我已经研究了一段时间,并尝试阅读其他SO技术。

From Aaron Bertrand 's example HERE , it looks like I can combine all of my select calls into one line: Aaron Bertrand的示例HERE看来,我可以将所有select调用合并到一行中:

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

Otherwise, I don't see anything more enlightening anywhere or see anyone asking about techniques to test triggers before creating them. 否则,我看不到任何启发性的地方,也看不到有人在创建触发器之前询问有关测试触发器的技术的问题。

One of my colleges here at work does more SQL work than I do, but he admits that he has never written triggers. 我在这里工作的一所大学比我做更多的SQL工作,但他承认他从未编写触发器。 All he was able to tell me was, "Man, if you screw that up, you could cause a lot of problems on the server!" 他只能告诉我, “伙计,如果您搞砸了,可能会在服务器上引起很多问题!” All that did was make me nervous, which is why I am here. 所有的事情使我感到紧张,这就是为什么我在这里。 (98% of what I do is write C# code for Windows Forms and old Windows Mobile devices). (我的98%是为Windows窗体和旧的Windows Mobile设备编写C#代码)。

So, how would I verify that this trigger is valid and will not cause any issues on the Server before creating? 因此,在创建之前,我将如何验证此触发器是否有效并且不会在服务器上引起任何问题? I've got a local SQL Server Express on my machine, but it is much newer than SQL 2000 and does not have the live data running on it from our Production floor. 我的机器上装有本地SQL Server Express,但它比SQL 2000更新得多,并且没有生产现场运行的实时数据。

If the trigger proves to be faulty afterwards, would I be able to remove it with a simple delete trigger trgAfterMachine1Insert ? 如果此后证明触发器有问题,我是否可以使用简单的delete trigger trgAfterMachine1Insert删除它? My search for "delete trigger" seems to have returned mostly triggers for AFTER DELETE . 我对“删除触发器”的搜索似乎大部分返回了AFTER DELETE触发器。

Thanks in advance. 提前致谢。

UPDATE: Including the stored procedure at Martin's request: 更新:应马丁的要求包括存储过程:

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

So, let me re-phrase what you are saying: 所以,让我重新表达一下你在说什么:

  • you have no experience writing triggers 您没有编写触发器的经验
  • there is no one else in the company with experience to write triggers 公司中没有其他人有编写触发器的经验
  • you only have a production environment and no other place to test you code 您只有生产环境,没有其他地方可以测试代码
  • management is telling you to get this done by tonight 管理层告诉您要在今晚之前完成

This is a sure recipe for disaster. 这肯定是灾难的秘诀。

First you need to stand up against requests where your only option is to fail. 首先,您需要面对唯一失败的请求。 Tell management that their data is too important to do something like this without proper testing. 告诉管理层,如果没有适当的测试,他们的数据太重要了而不能执行此类操作。

Then get an appropriate testing environment. 然后获得适当的测试环境。 If your company is a MSDN subscriber you will have access to a copy of SQL Server 2000 Developer Edition that you can install on you laptop or better in some virtual machine. 如果您的公司是MSDN订户,则可以访问SQL Server 2000 Developer Edition的副本,该副本可以安装在笔记本电脑上,也可以安装在某些虚拟机上。

While you are waiting for that install read about professional behavior in software development. 在等待安装期间,请阅读有关软件开发中专业行为的信息。 Start with http://en.wikipedia.org/wiki/Robert_Cecil_Martin and then go to software craftsmanship. http://en.wikipedia.org/wiki/Robert_Cecil_Martin开始,然后进入软件工艺。


But, as I know that won't happen tonight, you can do this in the meantime: 但是,据我所知,今晚不会发生这种情况,您可以同时执行以下操作:

1) Create a new database on the production server 1)在生产服务器上创建一个新数据库

2) Copy the table in question: SELECT TOP(10) * INTO NewDb.dbo.Table FROM OldDb.dbo.Table; 2)复制有问题的表: SELECT TOP(10) * INTO NewDb.dbo.Table FROM OldDb.dbo.Table; You don't need more data as this is an insert trigger 您不需要更多数据,因为这是一个插入触发器

3) Copy the other tables you need in the same way 3)以相同的方式复制您需要的其他表

4) apply your trigger to the table in NewDb 4)将触发器应用于NewDb中的表

5) test 5)测试

6) fix and go back to 5 6)修复并返回到5

7) if you are satisfied, copy the trigger to OldDb 7)如果满意,将触发器复制到OldDb

Some things to consider: 要考虑的一些事情:

  • Make sure you test inserts of more than one row 确保您测试的插入物不止一排
  • Don't call a procedure in the trigger. 不要在触发器中调用过程。 Not that that is wrong in it self, but you won't be able to get multi row inserts working with it 并不是说它本身就是错的,但是您将无法使用多行插入
  • do not ever use @@IDENTITY. 永远不要使用@@ IDENTITY。 That's an order. 那是命令 (reasons and solutions are here: http://sqlity.net/en/351/identity-crisis/ ) (原因和解决方案在这里: http : //sqlity.net/zh/351/identity-crisis/

After all that start looking into TDD in the database here: tSQLt.org (Most ideas work in SQL 2000, however the framework does not.) 在所有这些开始之后,您可以在这里查看数据库中的TDD: tSQLt.org (大多数想法在SQL 2000中有效,但是该框架无效)。

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM