Laden...

MS SQL 2005,Common Language Runtime (CLR) Trigger,delegate,Dienst

Letzter Beitrag vor 15 Jahren 2 Posts 2.988 Views
MS SQL 2005,Common Language Runtime (CLR) Trigger,delegate,Dienst

verwendetes Datenbanksystem: <bitte immer angeben>
Hallo,

ich habe eine Frage zur Erstellung eines Common Language Runtime (CLR) Triggers. Ziel ist es, dass Änderungen in der Datenbank (Insert, Update, Delete) einen Dienst-Programm mitgeteilt werden.

Folgende Schritte wurden bisher von mir ausgeführt:

  1. Erstellung einer neuen Klasse Class_CLRTriggers mit folgenden C#-Code:

using System;
using System.Collections.Generic;
using System.Text;
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 Class_CLRTriggers
{
  public delegate void myDelegate(int iID, string stName);
  public myDelegate onDBDataChanged_tabTasks;  

  //[Microsoft.SqlServer.Server.SqlProcedure]
  [SqlTrigger(Name = @"tabTest_InsertUpdate", Target = "[dbo].[tabTest]", Event = "FOR INSERT")]
  public static void tabTest_InsertUpdate()
  {
    int iID = 0;
    string stTaskName = "";
    string stDirectory = "";
    DateTime dtStartTime;

    SqlCommand command;    
    SqlTriggerContext triggContext = SqlContext.TriggerContext;
    SqlDataReader reader;

    switch (triggContext.TriggerAction)
    {
      case TriggerAction.Insert:
        using (SqlConnection connection = new SqlConnection(@"context connection = true"))
        {
          connection.Open();

          command = new SqlCommand(@"SELECT * from INSERTED;", connection);
          reader = command.ExecuteReader();
          reader.Read();
          iID = (int)reader["ID"];

          stTaskName = (string)reader["TaskName"];
          stDirectory = (string)reader["Directory"];
          dtStartTime = (DateTime)reader["StartTime"];
          reader.Close();

          onDBDataChanged_tabTasks(iID, stTaskName);//Verweis auf Methode im Dienst-Programm
          
          command = new SqlCommand(@"INSERT [dbo].[tabTest1] (TaskName,Directory,StartTime) "
            + @"VALUES (@TaskName,@Directory,@StartTime);", connection);

          command.Parameters.Add(new SqlParameter("@TaskName", stTaskName));          
          command.Parameters.Add(new SqlParameter("@Directory", stDirectory));
          command.Parameters.Add(new SqlParameter("@StartTime", dtStartTime));

          command.ExecuteNonQuery();

          break;
        }
      case TriggerAction.Update:
        command.CommandText = new SqlCommand(@"SELECT * from " + "inserted", connection);
        reader = command.ExecuteReader();
        iID = (int)reader["ID"];
        //...
        
        break;

      case TriggerAction.Delete:
        command.CommandText = new SqlCommand(@"SELECT * from " + "deleted", connection);
        reader = command.ExecuteReader();
        //...

        break;
    }
  }

  1. Erstellung einer Assembly im Verzeichnis C:\WINDOWS\Microsoft.NET\Framework\v3.5, danach Aufruf von
    C:\WINDOWS\Microsoft.NET\Framework\v3.5\csc /target:library Class_CLRTriggers.cs

  2. Bekanntmachen der Assembly in MS-SQL Server 2005:


USE [DB_Test]
      GO
      CREATE ASSEMBLY Class_CLRTriggers from 
      'C:\WINDOWS\Microsoft.NET\Framework\v3.5\Class_CLRTriggers.dll'
      WITH PERMISSION_SET = SAFE

  1. Erzeugen des Triggers mit folgenden SQL-Befehl:

USE [DB_Test]
      GO
      CREATE TRIGGER CLRTrigger
      ON dbo.tabTest
      FOR INSERT
      AS
      EXTERNAL NAME Class_CLRTriggers.Class_CLRTriggers.tabTest_InsertUpdate

  1. Dienst-Programm:
    Assembly wird unter Verweise hinzufügen dem Dienst bekannt gemacht.

In der Methode Load-Data wird folgende Zeile ausgeführt:

Class_CLRTriggers.onDBDataChanged_tabTest = new Class_CLRTriggers.myDelegate(DataChange_tabTest);

Deklarieren der Methode


public void DataChange_tabTest(int iID, string stName)
{
  //...
}

im Dienst-Programm.

Schreiben in Datenbank erfolgt mit CLR-Trigger, das würde aber auch mit T-SQL funktionieren. Problem ist die statische Methode "tabTest_InsertUpdate()", hier gelinkt es mir nicht den "Delegaten" zu verankern.
Hat jemand eine Idee, wie ich im Dienst-Programm auf DB-Ereignisse reagieren kann? Freue mich auf Anregungen von Euch.

Hi.

Hat keiner eine Idee? Würde mich nämlich auch interessieren. Mein jetziger (und einziger) Ansatzpunkt wäre eine WCF-Verbindung zum Dienst. Ist das möglich aus einem DB-Assembly raus? Und vor allem, ist es sinnvoll (Performance etc.)?
SQL-Server ist 2008. Sind zwar noch einige 2005er im Einsatz, die könnte man zur Not aber auf 2008 anheben.

Lars