Как я могу использовать триггеры? - PullRequest
2 голосов
/ 07 сентября 2010

У меня есть база данных с несколькими таблицами,
Я хочу запустить метод в C # всякий раз, когда некоторые данные записываются в таблицах.

Я знаю, что должен использовать триггеры, но я не знаю, как !!!
Буду признателен, если вы направите меня.

P.S .:
Я использую SQLExpress 2008

Ответы [ 3 ]

5 голосов
/ 07 сентября 2010

ADO.NET предоставляет очень полезный класс под названием SqlDependency.Вы можете подписаться на событие OnChange при изменении указанной таблицы в базе данных.

Вот документация и пример:

http://msdn.microsoft.com/en-us/library/62xk7953.aspx

Это выглядит очень хорошо и работает!

void Initialization()
{
    // Create a dependency connection.
    SqlDependency.Start(connectionString, queueName);
}

void SomeMethod()
{
    // Assume connection is an open SqlConnection.

    // Create a new SqlCommand object.
    using (SqlCommand command=new SqlCommand(
        "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", 
        connection))
    {

        // Create a dependency and associate it with the SqlCommand.
        SqlDependency dependency=new SqlDependency(command);
        // Maintain the refence in a class member.

        // Subscribe to the SqlDependency event.
        dependency.OnChange+=new
           OnChangeEventHandler(OnDependencyChange);

        // Execute the command.
        using (SqlDataReader reader = command.ExecuteReader())
        {
            // Process the DataReader.
        }
    }
}

// Handler method
void OnDependencyChange(object sender, 
   SqlNotificationEventArgs e )
{
  // Handle the event (for example, invalidate this cache entry).
}

void Termination()
{
    // Release the dependency.
    SqlDependency.Stop(connectionString, queueName);
}

Однако для получения этих уведомлений вам необходимо включить компонент Service Broker в вашей базе данных.Вот как это сделать:

--Create login if you do not have already
--Example:
--CREATE LOGIN ChangesMonitor WITH PASSWORD = 'ChangesMonitor' ;
--GO

--Create user associated with this login and
--add provilages in Management Studio tab Security->Users
--(not sure if all are needed, but for test purposes add following):
--db_datareader, db_datawriter,  db_ddladmin, db_accesadmin, db_owner, db_securityadmin



--must have exclusiveness on database
--script for database SqlDependExample and for user ChangesMonitor
ALTER DATABASE SqlDependExample SET ENABLE_BROKER
GO

GRANT CREATE PROCEDURE TO [ChangesMonitor];
GO
GRANT CREATE SERVICE TO [ChangesMonitor];
GO

GRANT CREATE QUEUE TO [ChangesMonitor];
GO

GRANT REFERENCES ON CONTRACT::[http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification] TO [ChangesMonitor];
GO
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO [ChangesMonitor];
GO

GRANT CONTROL ON SCHEMA::[dbo] TO [ChangesMonitor];
GO

GRANT IMPERSONATE ON USER::DBO TO [ChangesMonitor];
GO 
1 голос
/ 07 сентября 2010

Есть , есть некоторые опции для запуска .NET-кода в базе данных, но лично? Я бы не стал. Я хочу, чтобы моя база данных беспокоилась о хранении и получении данных, вот и все. Опции:

  • использовать триггер (или любой другой подход) для заполнения очереди событий, то есть другой таблицы; Ваше приложение C # опрашивает эту таблицу, чтобы узнать, что делать
  • вместо этого напишите код на уровне вашего приложения (то есть запустите код как часть выполнения команды data-change)

Также рассмотрите транзакционную природу базы данных - может случиться так, что даже если вы сделали INSERT / UPDATE, транзакция никогда не будет зафиксирована (обратите внимание, что при первом подходе вставка во вторую таблицу будет также будет автоматически откатываться одновременно, если все сделано правильно)

1 голос
/ 07 сентября 2010

Я думаю, что один из способов сделать это - создать функцию или хранимую процедуру, написанную на C #. Это возможно в SQL Server и DB2, например. Тогда ваш триггер сможет вызвать эту функцию SQL Server / SP.

Но, честно говоря, для меня это не выглядит хорошим дизайном.

...