Bagikan melalui


Pemicu CLR

Karena integrasi SQL Server dengan runtime bahasa umum .NET Framework (CLR), Anda dapat menggunakan bahasa .NET Framework apa pun untuk membuat pemicu CLR. Bagian ini mencakup informasi khusus untuk pemicu yang diterapkan dengan integrasi CLR. Untuk diskusi lengkap tentang pemicu, lihat Pemicu DDL.

Apa Itu Pemicu?

Pemicu adalah jenis prosedur tersimpan khusus yang berjalan secara otomatis saat peristiwa bahasa dijalankan. SQL Server mencakup dua jenis pemicu umum: pemicu bahasa manipulasi data (DML) dan bahasa definisi data (DDL). Pemicu DML dapat digunakan saat INSERTpernyataan , , UPDATEatau DELETE memodifikasi data dalam tabel atau tampilan tertentu. DDL memicu prosedur tersimpan kebakaran sebagai respons terhadap berbagai pernyataan DDL, yang terutama merupakan pernyataan yang dimulai dengan CREATE, ALTER, dan DROP. Pemicu DDL dapat digunakan untuk tugas administratif, seperti mengaudit dan mengatur operasi database.

Kemampuan Unik Pemicu CLR

Pemicu yang ditulis dalam Transact-SQL memiliki kemampuan menentukan kolom mana dari tampilan atau tabel penembakan yang telah diperbarui dengan menggunakan UPDATE(column) fungsi dan COLUMNS_UPDATED() .

Pemicu yang ditulis dalam bahasa CLR berbeda dari objek integrasi CLR lainnya dengan beberapa cara yang signifikan. Pemicu CLR dapat:

  • Mereferensikan INSERTED data dalam tabel dan DELETED

  • Menentukan kolom mana yang telah dimodifikasi sebagai hasil dari UPDATE operasi

  • Akses informasi tentang objek database yang terpengaruh oleh eksekusi pernyataan DDL.

Kemampuan ini disediakan secara inheren dalam bahasa kueri, atau oleh SqlTriggerContext kelas . Untuk informasi tentang keuntungan integrasi CLR dan memilih antara kode terkelola dan Transact-SQL, lihat Gambaran Umum Integrasi CLR.

Menggunakan Kelas SqlTriggerContext

Kelas SqlTriggerContext tidak dapat dibangun secara publik dan hanya dapat diperoleh dengan mengakses SqlContext.TriggerContext properti dalam isi pemicu CLR. Kelas SqlTriggerContext dapat diperoleh dari aktif SqlContext dengan memanggil SqlContext.TriggerContext properti:

SqlTriggerContext myTriggerContext = SqlContext.TriggerContext;

Kelas ini SqlTriggerContext menyediakan informasi konteks tentang pemicu. Informasi kontekstual ini mencakup jenis tindakan yang menyebabkan pemicu diaktifkan, kolom mana yang dimodifikasi dalam operasi UPDATE, dan, dalam kasus pemicu DDL, struktur XML EventData yang menjelaskan operasi pemicu. Untuk informasi selengkapnya, lihat EVENTDATA (Transact-SQL).

Menentukan Tindakan Pemicu

Setelah mendapatkan SqlTriggerContext, Anda dapat menggunakannya untuk menentukan jenis tindakan yang menyebabkan pemicu diaktifkan. Informasi ini tersedia melalui TriggerAction properti SqlTriggerContext kelas.

Untuk pemicu DML, TriggerAction properti bisa menjadi salah satu nilai berikut:

  • TriggerAction.Update (0x1)

  • TriggerAction.Insert (0x2)

  • TriggerAction.Delete(0x3)

  • Untuk pemicu DDL, daftar kemungkinan nilai TriggerAction jauh lebih lama. Silakan lihat "Enumerasi TriggerAction" di .NET Framework SDK untuk informasi selengkapnya.

Menggunakan Tabel yang Disisipkan dan Dihapus

Dua tabel khusus digunakan dalam pernyataan pemicu DML: tabel yang disisipkan dan tabel yang dihapus . SQL Server secara otomatis membuat dan mengelola tabel ini. Anda dapat menggunakan tabel sementara ini untuk menguji efek modifikasi data tertentu dan untuk mengatur kondisi untuk tindakan pemicu DML; namun, Anda tidak dapat mengubah data dalam tabel secara langsung.

Pemicu CLR dapat mengakses tabel yang disisipkan dan dihapus melalui penyedia dalam proses CLR. Ini dilakukan dengan mendapatkan SqlCommand objek dari objek SqlContext. Contohnya:

C#

SqlConnection connection = new SqlConnection ("context connection = true");  
connection.Open();  
SqlCommand command = connection.CreateCommand();  
command.CommandText = "SELECT * from " + "inserted";  

Visual Basic

Dim connection As New SqlConnection("context connection=true")  
Dim command As SqlCommand  
connection.Open()  
command = connection.CreateCommand()  
command.CommandText = "SELECT * FROM " + "inserted"  

Menentukan Kolom yang Diperbarui

Anda dapat menentukan jumlah kolom yang dimodifikasi oleh operasi UPDATE dengan menggunakan ColumnCount properti SqlTriggerContext objek. Anda dapat menggunakan IsUpdatedColumn metode , yang mengambil kolom ordinal sebagai parameter input, untuk menentukan apakah kolom diperbarui. Nilai True menunjukkan bahwa kolom telah diperbarui.

Misalnya, cuplikan kode ini (dari pemicu EmailAudit nanti dalam topik ini) mencantumkan semua kolom yang diperbarui:

C#

reader = command.ExecuteReader();  
reader.Read();  
for (int columnNumber = 0; columnNumber < triggContext.ColumnCount; columnNumber++)  
{  
   pipe.Send("Updated column "  
      + reader.GetName(columnNumber) + "? "  
   + triggContext.IsUpdatedColumn(columnNumber).ToString());  
 }  
  
 reader.Close();  

Visual Basic

reader = command.ExecuteReader()  
reader.Read()  
Dim columnNumber As Integer  
  
For columnNumber=0 To triggContext.ColumnCount-1  
  
   pipe.Send("Updated column " & reader.GetName(columnNumber) & _  
   "? " & triggContext.IsUpdatedColumn(columnNumber).ToString() )  
  
Next  
  
reader.Close()  

Mengakses EventData untuk Pemicu CLR DDL

Pemicu DDL, seperti pemicu reguler, prosedur tersimpan kebakaran sebagai respons terhadap suatu peristiwa. Tetapi tidak seperti pemicu DML, mereka tidak diaktifkan sebagai respons terhadap pernyataan UPDATE, INSERT, atau DELETE pada tabel atau tampilan. Sebaliknya, mereka menembak sebagai respons terhadap berbagai pernyataan DDL, yang terutama merupakan pernyataan yang dimulai dengan CREATE, ALTER, dan DROP. Pemicu DDL dapat digunakan untuk tugas administratif, seperti audit dan pemantauan operasi database dan perubahan skema.

Informasi tentang peristiwa yang mengaktifkan pemicu DDL tersedia di EventData properti SqlTriggerContext kelas. Properti ini berisi xml nilai. Skema xml menyertakan informasi tentang:

  • Waktu peristiwa.

  • ID Proses Sistem (SPID) koneksi di mana pemicu dijalankan.

  • Jenis peristiwa yang mengaktifkan pemicu.

Kemudian, tergantung pada jenis peristiwa, skema menyertakan informasi tambahan, seperti database tempat peristiwa terjadi, objek tempat peristiwa terjadi, dan perintah Transact-SQL peristiwa.

Dalam contoh berikut, pemicu DDL berikut mengembalikan properti mentah EventData .

Nota

Mengirim hasil dan pesan melalui SqlPipe objek ditampilkan di sini hanya untuk tujuan ilustrasi dan umumnya tidak dianjurkan untuk kode produksi saat memprogram pemicu CLR. Data tambahan yang dikembalikan mungkin tidak terduga dan menyebabkan kesalahan aplikasi.

C#

using System;  
using System.Data;  
using System.Data.Sql;  
using Microsoft.SqlServer.Server;  
using System.Data.SqlClient;  
using System.Data.SqlTypes;  
using System.Xml;  
using System.Text.RegularExpressions;  
  
public class CLRTriggers  
{  
   public static void DropTableTrigger()  
   {  
       SqlTriggerContext triggContext = SqlContext.TriggerContext;             
  
       switch(triggContext.TriggerAction)  
       {  
           case TriggerAction.DropTable:  
           SqlContext.Pipe.Send("Table dropped! Here's the EventData:");  
           SqlContext.Pipe.Send(triggContext.EventData.Value);  
           break;  
  
           default:  
           SqlContext.Pipe.Send("Something happened! Here's the EventData:");  
           SqlContext.Pipe.Send(triggContext.EventData.Value);  
           break;  
       }  
   }  
}  

Visual Basic

Imports System  
Imports System.Data  
Imports System.Data.Sql  
Imports System.Data.SqlTypes  
Imports Microsoft.SqlServer.Server  
Imports System.Data.SqlClient  
  
'The Partial modifier is only required on one class definition per project.  
Partial Public Class CLRTriggers   
  
    Public Shared Sub DropTableTrigger()  
        Dim triggContext As SqlTriggerContext  
        triggContext = SqlContext.TriggerContext  
  
        Select Case triggContext.TriggerAction  
           Case TriggerAction.DropTable  
              SqlContext.Pipe.Send("Table dropped! Here's the EventData:")  
              SqlContext.Pipe.Send(triggContext.EventData.Value)  
  
           Case Else  
              SqlContext.Pipe.Send("Something else happened! Here's the EventData:")  
              SqlContext.Pipe.Send(triggContext.EventData.Value)  
  
        End Select  
    End Sub  
End Class     

Contoh output berikut adalah EventData nilai properti setelah pemicu DDL diaktifkan oleh CREATE TABLE peristiwa:

<EVENT_INSTANCE><PostTime>2004-04-16T21:17:16.160</PostTime><SPID>58</SPID><EventType>CREATE_TABLE</EventType><ServerName>MACHINENAME</ServerName><LoginName>MYDOMAIN\myname</LoginName><UserName>MYDOMAIN\myname</UserName><DatabaseName>AdventureWorks</DatabaseName><SchemaName>dbo</SchemaName><ObjectName>UserName</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" /><CommandText>create table dbo.UserName ( UserName varchar(50), RealName varchar(50) ) </CommandText></TSQLCommand></EVENT_INSTANCE>

Selain informasi yang dapat diakses melalui SqlTriggerContext kelas, kueri masih dapat merujuk dan COLUMNS_UPDATED disisipkan/dihapus dalam teks perintah yang dijalankan dalam proses.

Contoh Pemicu CLR

Dalam contoh ini, pertimbangkan skenario di mana Anda membiarkan pengguna memilih ID apa pun yang mereka inginkan, tetapi Anda ingin mengetahui pengguna yang secara khusus memasukkan alamat email sebagai ID. Pemicu berikut akan mendeteksi informasi tersebut dan mencatatnya ke tabel audit.

Nota

Mengirim hasil dan pesan melalui SqlPipe objek ditampilkan di sini hanya untuk tujuan ilustrasi dan umumnya tidak dianjurkan untuk kode produksi. Data tambahan yang dikembalikan mungkin tidak terduga dan menyebabkan kesalahan aplikasi

using System;  
using System.Data;  
using System.Data.Sql;  
using Microsoft.SqlServer.Server;  
using System.Data.SqlClient;  
using System.Data.SqlTypes;  
using System.Xml;  
using System.Text.RegularExpressions;  
  
public class CLRTriggers  
{  
   [SqlTrigger(Name = @"EmailAudit", Target = "[dbo].[Users]", Event = "FOR INSERT, UPDATE, DELETE")]  
   public static void EmailAudit()  
   {  
      string userName;  
      string realName;  
      SqlCommand command;  
      SqlTriggerContext triggContext = SqlContext.TriggerContext;  
      SqlPipe pipe = SqlContext.Pipe;  
      SqlDataReader reader;  
  
      switch (triggContext.TriggerAction)  
      {  
         case TriggerAction.Insert:  
         // Retrieve the connection that the trigger is using  
         using (SqlConnection connection  
            = new SqlConnection(@"context connection=true"))  
         {  
            connection.Open();  
            command = new SqlCommand(@"SELECT * FROM INSERTED;",  
               connection);  
            reader = command.ExecuteReader();  
            reader.Read();  
            userName = (string)reader[0];  
            realName = (string)reader[1];  
            reader.Close();  
  
            if (IsValidEMailAddress(userName))  
            {  
               command = new SqlCommand(  
                  @"INSERT [dbo].[UserNameAudit] VALUES ('"  
                  + userName + @"', '" + realName + @"');",  
                  connection);  
               pipe.Send(command.CommandText);  
               command.ExecuteNonQuery();  
               pipe.Send("You inserted: " + userName);  
            }  
         }  
  
         break;  
  
         case TriggerAction.Update:  
         // Retrieve the connection that the trigger is using  
         using (SqlConnection connection  
            = new SqlConnection(@"context connection=true"))  
         {  
            connection.Open();  
            command = new SqlCommand(@"SELECT * FROM INSERTED;",  
               connection);  
            reader = command.ExecuteReader();  
            reader.Read();  
  
            userName = (string)reader[0];  
            realName = (string)reader[1];  
  
            pipe.Send(@"You updated: '" + userName + @"' - '"  
               + realName + @"'");  
  
            for (int columnNumber = 0; columnNumber < triggContext.ColumnCount; columnNumber++)  
            {  
               pipe.Send("Updated column "  
                  + reader.GetName(columnNumber) + "? "  
                  + triggContext.IsUpdatedColumn(columnNumber).ToString());  
            }  
  
            reader.Close();  
         }  
  
         break;  
  
         case TriggerAction.Delete:  
            using (SqlConnection connection  
               = new SqlConnection(@"context connection=true"))  
               {  
                  connection.Open();  
                  command = new SqlCommand(@"SELECT * FROM DELETED;",  
                     connection);  
                  reader = command.ExecuteReader();  
  
                  if (reader.HasRows)  
                  {  
                     pipe.Send(@"You deleted the following rows:");  
                     while (reader.Read())  
                     {  
                        pipe.Send(@"'" + reader.GetString(0)  
                        + @"', '" + reader.GetString(1) + @"'");  
                     }  
  
                     reader.Close();  
  
                     //alternately, to just send a tabular resultset back:  
                     //pipe.ExecuteAndSend(command);  
                  }  
                  else  
                  {  
                     pipe.Send("No rows affected.");  
                  }  
               }  
  
               break;  
            }  
        }  
  
     public static bool IsValidEMailAddress(string email)  
     {  
         return Regex.IsMatch(email, @"^([\w-]+\.)*?[\w-]+@[\w-]+\.([\w-]+\.)*?[\w]+$");  
     }  
}  

Visual Basic

Imports System  
Imports System.Data  
Imports System.Data.Sql  
Imports System.Data.SqlTypes  
Imports Microsoft.SqlServer.Server  
Imports System.Data.SqlClient  
Imports System.Text.RegularExpressions  
  
'The Partial modifier is only required on one class definition per project.  
Partial Public Class CLRTriggers   
  
    <SqlTrigger(Name:="EmailAudit", Target:="[dbo].[Users]", Event:="FOR INSERT, UPDATE, DELETE")> _  
    Public Shared Sub EmailAudit()  
        Dim userName As String  
        Dim realName As String  
        Dim command As SqlCommand  
        Dim triggContext As SqlTriggerContext  
        Dim pipe As SqlPipe  
        Dim reader As SqlDataReader    
  
        triggContext = SqlContext.TriggerContext      
        pipe = SqlContext.Pipe    
  
        Select Case triggContext.TriggerAction  
           Case TriggerAction.Insert  
              Using connection As New SqlConnection("context connection=true")  
                 connection.Open()  
                 command = new SqlCommand("SELECT * FROM INSERTED;", connection)  
  
                 reader = command.ExecuteReader()  
                 reader.Read()  
  
                 userName = CType(reader(0), String)  
                 realName = CType(reader(1), String)  
  
                 reader.Close()  
  
                 If IsValidEmailAddress(userName) Then  
                     command = New SqlCommand("INSERT [dbo].[UserNameAudit] VALUES ('" & _  
                       userName & "', '" & realName & "');", connection)  
  
                    pipe.Send(command.CommandText)  
                    command.ExecuteNonQuery()  
                    pipe.Send("You inserted: " & userName)  
  
                 End If  
              End Using  
  
           Case TriggerAction.Update  
              Using connection As New SqlConnection("context connection=true")  
                 connection.Open()  
                 command = new SqlCommand("SELECT * FROM INSERTED;", connection)  
  
                 reader = command.ExecuteReader()  
                 reader.Read()  
  
                 userName = CType(reader(0), String)  
                 realName = CType(reader(1), String)  
  
                 pipe.Send("You updated: " & userName & " - " & realName)  
  
                 Dim columnNumber As Integer  
  
                 For columnNumber=0 To triggContext.ColumnCount-1  
  
                    pipe.Send("Updated column " & reader.GetName(columnNumber) & _  
                      "? " & triggContext.IsUpdatedColumn(columnNumber).ToString() )  
  
                 Next  
  
                 reader.Close()  
              End Using  
  
           Case TriggerAction.Delete  
              Using connection As New SqlConnection("context connection=true")  
                 connection.Open()  
                 command = new SqlCommand("SELECT * FROM DELETED;", connection)  
  
                 reader = command.ExecuteReader()  
  
                 If reader.HasRows Then  
                    pipe.Send("You deleted the following rows:")  
  
                    While reader.Read()  
  
                       pipe.Send( reader.GetString(0) & ", " & reader.GetString(1) )  
  
                    End While   
  
                    reader.Close()  
  
                    ' Alternately, just send a tabular resultset back:  
                    ' pipe.ExecuteAndSend(command)  
  
                 Else  
                   pipe.Send("No rows affected.")  
                 End If  
  
              End Using   
        End Select  
    End Sub  
  
    Public Shared Function IsValidEMailAddress(emailAddress As String) As Boolean  
  
       return Regex.IsMatch(emailAddress, "^([\w-]+\.)*?[\w-]+@[\w-]+\.([\w-]+\.)*?[\w]+$")  
    End Function      
End Class  

Dengan asumsi ada dua tabel dengan definisi berikut:

CREATE TABLE Users  
(  
    UserName nvarchar(200) NOT NULL,  
    RealName nvarchar(200) NOT NULL  
);  
GO CREATE TABLE UserNameAudit  
(  
    UserName nvarchar(200) NOT NULL,  
    RealName nvarchar(200) NOT NULL  
)  

Pernyataan Transact-SQL yang membuat pemicu di SQL Server adalah sebagai berikut, dan mengasumsikan rakitan SQLCLRTest sudah terdaftar dalam database SQL Server saat ini.

CREATE TRIGGER EmailAudit  
ON Users  
FOR INSERT, UPDATE, DELETE  
AS  
EXTERNAL NAME SQLCLRTest.CLRTriggers.EmailAudit  

Memvalidasi dan Membatalkan Transaksi yang Tidak Valid

Menggunakan pemicu untuk memvalidasi dan membatalkan transaksi INSERT, UPDATE, atau DELETE yang tidak valid atau untuk mencegah perubahan pada skema database Anda adalah umum. Ini dapat dicapai dengan memasukkan logika validasi ke dalam pemicu Anda dan kemudian mengembalikan transaksi saat ini jika tindakan tidak memenuhi kriteria validasi.

Ketika dipanggil dalam pemicu, Transaction.Rollback metode atau SqlCommand dengan teks perintah "ROLLBACK TRANSAKSI" melemparkan pengecualian dengan pesan kesalahan ambigu dan harus dibungkus dalam blok coba/tangkap. Pesan kesalahan yang Anda lihat mirip dengan yang berikut ini:

Msg 6549, Level 16, State 1, Procedure trig_InsertValidator, Line 0  
A .NET Framework error occurred during execution of user defined routine or aggregate 'trig_InsertValidator':   
System.Data.SqlClient.SqlException: Transaction is not allowed to roll back inside a user defined routine, trigger or aggregate because the transaction is not started in that CLR level. Change application logic to enforce strict transaction nesting... User transaction, if any, will be rolled back.  

Pengecualian ini diharapkan dan blok try/catch diperlukan agar eksekusi kode berlanjut. Ketika kode pemicu selesai dieksekusi, pengecualian lain dinaikkan

Msg 3991, Level 16, State 1, Procedure trig_InsertValidator, Line 1   
The context transaction which was active before entering user defined routine, trigger or aggregate "trig_InsertValidator" has been ended inside of it, which is not allowed. Change application logic to enforce strict transaction nesting.  
The statement has been terminated.  

Pengecualian ini juga diharapkan, dan blok coba/tangkap di sekitar pernyataan Transact-SQL yang melakukan tindakan yang menembakkan pemicu diperlukan sehingga eksekusi dapat berlanjut. Meskipun dua pengecualian dilemparkan, transaksi digulung balik dan perubahan tidak diterapkan pada tabel. Perbedaan utama antara pemicu CLR dan pemicu Transact-SQL adalah bahwa pemicu Transact-SQL dapat terus melakukan lebih banyak pekerjaan setelah transaksi digulung balik.

Contoh

Pemicu berikut melakukan validasi sederhana pernyataan INSERT pada tabel. Jika nilai bilangan bulat yang disisipkan sama dengan satu, transaksi digulung balik dan nilai tidak dimasukkan ke dalam tabel. Semua nilai bilangan bulat lainnya disisipkan ke dalam tabel. Perhatikan blok coba/tangkap di Transaction.Rollback sekitar metode . Skrip Transact-SQL membuat tabel pengujian, perakitan, dan prosedur tersimpan terkelola. Perhatikan bahwa dua pernyataan INSERT dibungkus dalam blok coba/tangkap sehingga pengecualian dilemparkan ketika pemicu selesai eksekusi tertangkap.

C#

using System;  
using System.Data.SqlClient;  
using Microsoft.SqlServer.Server;  
using System.Transactions;  
  
public partial class Triggers  
{  
    // Enter existing table or view for the target and uncomment the attribute line  
    // [Microsoft.SqlServer.Server.SqlTrigger (Name="trig_InsertValidator", Target="Table1", Event="FOR INSERT")]  
    public static void trig_InsertValidator()  
    {  
        using (SqlConnection connection = new SqlConnection(@"context connection=true"))  
        {  
            SqlCommand command;  
            SqlDataReader reader;  
            int value;  
  
            // Open the connection.  
            connection.Open();  
  
            // Get the inserted value.  
            command = new SqlCommand(@"SELECT * FROM INSERTED", connection);  
            reader = command.ExecuteReader();  
            reader.Read();  
            value = (int)reader[0];  
            reader.Close();  
  
            // Rollback the transaction if a value of 1 was inserted.  
            if (1 == value)  
            {  
                try  
                {  
                    // Get the current transaction and roll it back.  
                    Transaction trans = Transaction.Current;  
                    trans.Rollback();                      
                }  
                catch (SqlException ex)  
                {  
                    // Catch the expected exception.                      
                }  
            }  
            else  
            {  
                // Perform other actions here.  
            }  
  
            // Close the connection.  
            connection.Close();              
        }  
    }  
}  

Visual Basic

Imports System  
Imports System.Data.SqlClient  
Imports System.Data.SqlTypes  
Imports Microsoft.SqlServer.Server  
Imports System.Transactions  
  
Partial Public Class Triggers  
' Enter existing table or view for the target and uncomment the attribute line  
' <Microsoft.SqlServer.Server.SqlTrigger(Name:="trig_InsertValidator", Target:="Table1", Event:="FOR INSERT")> _  
Public Shared Sub  trig_InsertValidator ()  
    Using connection As New SqlConnection("context connection=true")  
  
        Dim command As SqlCommand  
        Dim reader As SqlDataReader  
        Dim value As Integer  
  
        ' Open the connection.  
        connection.Open()  
  
        ' Get the inserted value.  
        command = New SqlCommand("SELECT * FROM INSERTED", connection)  
        reader = command.ExecuteReader()  
        reader.Read()  
        value = CType(reader(0), Integer)  
        reader.Close()  
  
        ' Rollback the transaction if a value of 1 was inserted.  
        If value = 1 Then  
  
            Try  
                ' Get the current transaction and roll it back.  
                Dim trans As Transaction  
                trans = Transaction.Current  
                trans.Rollback()  
  
            Catch ex As SqlException  
  
                ' Catch the exception.                      
            End Try  
        Else  
  
            ' Perform other actions here.  
        End If  
  
        ' Close the connection.  
        connection.Close()  
    End Using  
End Sub  
End Class  

Transact-SQL

-- Create the test table, assembly, and trigger.  
CREATE TABLE Table1(c1 int);  
go  
  
CREATE ASSEMBLY ValidationTriggers from 'E:\programming\ ValidationTriggers.dll';  
go  
  
CREATE TRIGGER trig_InsertValidator  
ON Table1  
FOR INSERT  
AS EXTERNAL NAME ValidationTriggers.Triggers.trig_InsertValidator;  
go  
  
-- Use a Try/Catch block to catch the expected exception  
BEGIN TRY  
   INSERT INTO Table1 VALUES(42)  
   INSERT INTO Table1 VALUES(1)  
END TRY  
BEGIN CATCH  
  SELECT ERROR_NUMBER() AS ErrorNum, ERROR_MESSAGE() AS ErrorMessage  
END CATCH;  
  
-- Clean up.  
DROP TRIGGER trig_InsertValidator;  
DROP ASSEMBLY ValidationTriggers;  
DROP TABLE Table1;  

Lihat Juga

BUAT PEMICU (Transact-SQL)
Pemicu DML
Pemicu DDL
COBA... CATCH (Transact-SQL)
Membangun Objek Database dengan Integrasi Common Language Runtime (CLR)
EVENTDATA (Transact-SQL)