Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Простейшая ситуация. Делаем запрос например самый простой Select * from Table1
Выводим его в грид или ещё куда. Теперь если данные в таблице изменились надо запрос обновить. Собственно может ли MS SQL как-то сообщить об этом клиенту?

Напимер в InterBase можно было послать Event Alert тиггером и по нему отрефрешить. Есть что-то подобное в MS SQL?
24 фев 09, 18:36    [6855690]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mr Marmelad
Member [заблокирован]

Откуда: Boston MA
Сообщений: 2957
Коллега, SQL Server может делать всё что Вы попросите. И обновлять и сообщать и предупреждать. Способов - вагон и малая тележка. Только ищите.
24 фев 09, 18:46    [6855732]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Mr Marmelad
Коллега, SQL Server может делать всё что Вы попросите. И обновлять и сообщать и предупреждать. Способов - вагон и малая тележка. Только ищите.


Догадываюсь, тока подскажите где искать, а то так сразу не смог найти пока ещё не очень в нём разбираюсь.
24 фев 09, 18:55    [6855788]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mr Marmelad
Member [заблокирован]

Откуда: Boston MA
Сообщений: 2957
Multy,

Ну например вот этот способ мы называем репликацией

Но имейте ввиду Коллега, каков вопрос таков ответ...
24 фев 09, 19:03    [6855825]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Вот, например, давно была тема: Уведомление клиента о событии на SQL-сервере! НОВОЕ РЕШЕНИЕ!
24 фев 09, 19:52    [6855982]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Mr Marmelad
Multy,

Ну например вот этот способ мы называем репликацией

Но имейте ввиду Коллега, каков вопрос таков ответ...



Что то вы по моему не о том, или я не точно выразился. Причём тут репликации?

Нужно обновить данные у клиента.

Типичный пример котировки акций.
Клиент интересуется определёнными акциями, посылает запрос:
Select * from Table1 получает таблицу например:

Акции "Гаспром"
Цена Количество
100 10
109 50
110 1000

И т.д. но котировки постоянно меняются другими клиентами, вот это и надо обновлять у клиента, канешно можно делать рефрешь 10 раз в секунду, но это нам не надо.
Надо делать обновление только когда данные изменятся.

Так вот в InterBase можно было при изменении данных послать Event Alert тиггером и по нему отрефрешить. Есть что-то подобное в MS SQL?
24 фев 09, 20:00    [6856011]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
iap
Вот, например, давно была тема: Уведомление клиента о событии на SQL-сервере! НОВОЕ РЕШЕНИЕ!

Сложные предлагаются методы.

Неужели MS SQL на столько крут и не может предоставить простого решения, которе было у InterBase в первых версиях?
24 фев 09, 20:08    [6856028]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Multy
Неужели MS SQL на столько крут и не может предоставить простого решения, которе было у InterBase в первых версиях?
Multy
Напимер в InterBase можно было послать Event Alert тиггером и по нему отрефрешить. Есть что-то подобное в MS SQL?
А что нужно ещё и тригер писать?
"А что пистолет ещё надо и в руках держать? Так это совсем для детей!" ©
Согласен, пример с BOL-а жутковатый:
ALTER DATABASE AdventureWorks SET ENABLE_BROKER; 
CREATE QUEUE ContactChangeMessages;
CREATE SERVICE ContactChangeNotifications ON QUEUE ContactChangeMessages ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);
C#
// queueName = "ContactChangeMessages"
void Initialization() { SqlDependency.Start(connectionString, queueName); }
void SomeMethod() {
SqlCommand command = new SqlCommand("SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", connection);
new SqlDependency(command).OnChange += new OnChangeEventHandler(OnDependencyChange);
command.ExecuteReader();
}
void OnDependencyChange(object sender, SqlNotificationsEventArgs e) {
// Handle the event (for example, invalidate this cache entry).
}
void Termination() { SqlDependency.Stop(connectionString, queueName); }
Теже event-ы, вид сбоку.
24 фев 09, 22:11    [6856338]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mr Marmelad
Member [заблокирован]

Откуда: Boston MA
Сообщений: 2957
:
Но имейте ввиду Коллега, каков вопрос таков ответ...

Коллега Я то как раз Вас хорошо понял... Это я над вопросом ерничаю....
TOPIC
Как узнать про изменение данных на сервере?

ответ - подписаться на репликацию
:
Причём тут репликации?

Один из видов уведомления об изменении на сервере. Другие: почтовая рассылка, триггеры, нотификации и так далее
24 фев 09, 22:21    [6856359]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Mnior
Multy
Неужели MS SQL на столько крут и не может предоставить простого решения, которе было у InterBase в первых версиях?
Multy
Напимер в InterBase можно было послать Event Alert тиггером и по нему отрефрешить. Есть что-то подобное в MS SQL?
А что нужно ещё и тригер писать?
"А что пистолет ещё надо и в руках держать? Так это совсем для детей!" ©
Согласен, пример с BOL-а жутковатый:
ALTER DATABASE AdventureWorks SET ENABLE_BROKER; 
CREATE QUEUE ContactChangeMessages;
CREATE SERVICE ContactChangeNotifications ON QUEUE ContactChangeMessages ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);
C#
// queueName = "ContactChangeMessages"
void Initialization() { SqlDependency.Start(connectionString, queueName); }
void SomeMethod() {
SqlCommand command = new SqlCommand("SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", connection);
new SqlDependency(command).OnChange += new OnChangeEventHandler(OnDependencyChange);
command.ExecuteReader();
}
void OnDependencyChange(object sender, SqlNotificationsEventArgs e) {
// Handle the event (for example, invalidate this cache entry).
}
void Termination() { SqlDependency.Stop(connectionString, queueName); }
Теже event-ы, вид сбоку.


Попробую разобраться как это работает, пока в Transact-SQL не особо руль.

Тока вот сразу вопрос возник, мне это всё надо под ASP.NET, а в примере http://msdn.microsoft.com/ru-ru/library/9dz445ks.aspx описывается тока отслеживания изменения кеша,
а надо именно типа:

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

Можно это как-то под ASP.NET прикрутить? Что бы обновление страницы, или части страницы, в баузере производилось тока тогда когда произошли изменения в базе.
24 фев 09, 23:31    [6856468]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
По асп.нет есть отдельный форум.
25 фев 09, 00:13    [6856532]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Гавриленко Сергей Алексеевич
По асп.нет есть отдельный форум.


Попробуем и там, тока там скорее всего особых рулей по SQL нету, как здесь по ASP.NET. Где бы универсального руля найти? :-):-)
25 фев 09, 10:03    [6857201]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
Ответ:практически никак.
Ибо нужно точно знать, что именно выбрано в Вашем датасете.
Для этого придется знать как минимум полное условие выборки.
Затем в бекграунде сравнивать текущие и ранее выбранные данные. Малой кровью не получится.
Частично можно решить проблему триггерами, если логировать изменения и подчитывать их со сравнением, но это решение зависит от задачи.

ЗЫ: Именно поэтому аналог Event Alert был не нужен, ибо в общем случае был бы неэффективен.
25 фев 09, 14:10    [6858791]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
LSV,
Что значит не эффективен в общем случае?

В InterBase требовалось создать на Insert, и Delete по триггеру с одной строчкой
PostEvent, на Update можно проветять типа If new.field1<>old.field1 Then PostEvent,
а можно и забить на все проверке, зарегистрировать алерт, а на клиенте по получению алерта обновить. Всё делается как 2 пальца обоссать.

При желании в сообщении можно закодировать, что изменилось конкретно.

Почему разработчики MS этого не сделали не понимаю, причём в Oracle, DB2 Event Alert точно есть, да и большенстве остальных думаю тоже.
25 фев 09, 15:02    [6859164]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mr Marmelad
Member [заблокирован]

Откуда: Boston MA
Сообщений: 2957
Multy
да и большенстве остальных думаю тоже.


Нет Коллега, В Sybase такой структуры нет а MS SQL Server именно продукт в своё время отпочковавшийся от Sybase SQL Server
25 фев 09, 16:36    [6859970]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Сделал всё как по документации:

ALTER DATABASE Test1 SET ENABLE_BROKER;
CREATE QUEUE ContactChangeMessages;
CREATE SERVICE ContactChangeNotifications ON QUEUE ContactChangeMessages ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection("Data Source=MSServer;Initial Catalog=Test1;Integrated Security=True"))
{
SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.Table1", connection);

new SqlDependency(cmd).OnChange += new OnChangeEventHandler(OnDataChange);

connection.Open();
//SqlDependency.Start("Data Source=MSServer;Initial Catalog=Test1;Integrated Security=True", "ContactChangeMessages");
SqlDataReader rdr = cmd.ExecuteReader();
}

}
public void OnDataChange(object sender, SqlNotificationEventArgs e)
{
Label1.Text = "1";
}


private void Form1_Load(object sender, EventArgs e)
{
SqlDependency.Start("Data Source=MSServer;Initial Catalog=Test1;Integrated Security=True", "ContactChangeMessages");
}

}
}


Доходит до cmd.ExecuteReader() и выдаёт:Если SqlDependency используется без указания значения для Оptions, то перед выполнением команды, добавленной в экземпляр SqlDependency, необходимо вызвать метод SqlDependency.Start(). Даже если вызовем непосредственно перед cmd.ExecuteReader() всё равно таже хрень.

В чём может быть дело?
28 фев 09, 16:27    [6873418]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Да, нужны уточнения. Если указывать в SqlDependency.Start(sqlConnectionString, QueueName), тогда надо подписываться так:
new SqlDependency(sqlCommand, "Service=ServiceName", 0).
Где QueueName и ServiceName руками созданные очередь и сервис. Но можно не создавать самому, а предоставить приложению: SqlDependency.Start(sqlConnectionString) и new SqlDependency(sqlCommand), т.е. очередь и сервис сами создадутся и удалятся командами Start и Stop соответственно.
+ Рабочий пример
USE tempdb
CREATE TABLE [dbo].[Test] (ID Int IDENTITY PRIMARY KEY, [Name] SysName)
Вешаем на форму грид dataGrid и добавляем код:
SqlCommand sqlCmnd;
private void FormMain_Load(object sender, EventArgs e)
{
	dataGrid.DataSource = new DataTable();
	sqlCmnd = new SqlCommand("SELECT ID, Name FROM dbo.Test", new SqlConnection("Data Source=.;Initial Catalog=tempdb;Integrated Security=True"));
	SqlDependency.Start(sqlCmnd.Connection.ConnectionString);
	sqlDependency_OnChange(null, null);
}
private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
{
	SqlDependency.Stop(sqlCmnd.Connection.ConnectionString);
}
void sqlDependency_OnChange(object sender, SqlNotificationEventArgs e)
{
	((DataTable)dataGrid.DataSource).Clear();
	sqlCmnd.Notification = null;
	new SqlDependency(sqlCmnd).OnChange += new OnChangeEventHandler(sqlDependency_OnChange);
	using (SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCmnd))
		sqlDA.Fill((DataTable)dataGrid.DataSource);
	}
}
Благо что DataTable работают в многопотоковом режиме. А вот для наблюдения работоспособности:
WHILE (1=1) BEGIN
	WHILE (@@RowCount <= 3) BEGIN
		WAITFOR DELAY '0:0:3'
		INSERT	dbo.Test
		SELECT	[Name]
		FROM	dbo.Test
		UNION	ALL
		SELECT	'Test'
	END
	WAITFOR DELAY '0:0:3'
	UPDATE	dbo.Test
	SET	Name = '123'
	WAITFOR DELAY '0:0:3'
	DELETE	dbo.Test
END
У обоих вариантов есть свои нюансы, например, надо как-то гарантировать уничтожение очередей или незакрытых диалогов, после збоев приложений. Для контроля:
SELECT * FROM sys.services
SELECT * FROM sys.service_queues
SELECT * FROM sys.conversation_groups
SELECT * FROM sys.conversation_endpoints
1 мар 09, 03:23    [6874065]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Mnior
Да, нужны уточнения. Если указывать в SqlDependency.Start(sqlConnectionString, QueueName), тогда надо подписываться так:
new SqlDependency(sqlCommand, "Service=ServiceName", 0).

Руки бы оторвать тем, кто в документации ни слова про это не написал.

А так большое спасибо всем, кто отвечал, похоже работает :-)

Только вот при данной реализации каждый когда приходит уведомление настройки теряются и их приходтся перепривязывать заново, что канешно не очень хорошо. Хотя SqlDependency.Stop я не вызываю, нельзя ли сделать это бы уведомление висело постоянно? Пока не будет явно закрыто.

И ещё как я понимаю на каждую юзер сессиию нужно делать новое уведомление или можно обойтись одним и тем же если они вызывают один и тот же запрос?
1 мар 09, 13:25    [6874291]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
+ OffTop
Multy
Только вот при данной реализации каждый когда приходит уведомление настройки теряются и их приходтся перепривязывать заново, что канешно не очень хорошо. нельзя ли сделать это бы уведомление висело постоянно?
уведомление, теряются настройки, перепривязывать, висело...
Каша какая-то. Понимаю, канэшно, что сделайте мне хорошо, но вы хоть сами поняли чё спрашиваете?

Я вам показал вариант реализующий данную логику: постоянное обновление данных при неизменном запросе и SqlDependency к данной логике не имеет никакого отношения, надо вам такую логику применить во многих местах, оберните в class, например. Если бы мелкие реализовали бы этот вариант на уровне самого SqlDependency, я б оторвал бы одно место данному горе программеру, при первой возможности.

Multy
Пока не будет явно закрыто ... Хотя SqlDependency.Stop я не вызываю


Multy
И ещё как я понимаю на каждую юзер сессиию нужно делать новое уведомление или можно обойтись одним и тем же если они вызывают один и тот же запрос?
А вы сами думать не пробовали? Лень? Пусть другие за вас работу сделают? Притом, постановку задачи узнают телепатически?
Не советую создавать "новые уведомления" когда на марсе идут песчаные бури и начинают летать крокодилы. Не сезон.
1 мар 09, 22:00    [6874863]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать про изменение данных на сервере?  [new]
Multy
Member [заблокирован]

Откуда:
Сообщений: 420
Думать оно можно когда знаешь над чём, когда не знаешь думать можно бесконечно. Когда знаешь T-SQL несколько дней всё не так просто.
В моём понимании для того и существуют форумы, что бы не тратить по нескольку дней над какой-нибудь глупостью которая для кого-та не представляет проблемы, и даже кажется смешной.

Впрочем я уже нащёл всё, что надо, в том числе и как заводить под ASP.NET.

Спасибо всем кто помог :)
2 мар 09, 00:10    [6874975]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Как узнать про изменение данных на сервере?  [new]
TwoRS
Member

Откуда:
Сообщений: 113
Прочитал и Ваши ответы и подобные, у меня аналогичная ситуация, только не могу разобраться, пожалуйста напишите мне
https://www.sql.ru/forum/actualthread.aspx?tid=939330
10 май 12, 23:38    [12533349]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить