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

Откуда:
Сообщений: 316
День добрый.

Нужно отслеживать состояние некоторой таблицы, и когда в ней появляются новые строки, отправить содержимое этой строки на определенный адрес и порт (хотя возможно при этом придется еще выполнить некий промежуточный запрос и уже его результаты отправлять). Можно ли это сделать прямо из Transact-SQL? Или нужно обязательно использовать CLR и C# или VB? Есть ли шанс прикрутить, например, DLL сделанную на Delphi? Подскажите, пожалуйста, оптимальный путь решения задачи. Пока не хочется делать приложения, которое будет мониторить состояние этой таблицы.
12 июн 17, 13:46    [20557903]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
AleksVoronezh,

очень порочная практика делать потусторонние вещи в триггерах. А так да хоть XP_cmdshell хоть библиотеку прикрутить можно
12 июн 17, 13:58    [20557924]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36698
SSIS-пакет + джоба решают проблему.
12 июн 17, 14:02    [20557930]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Сорри, забыл указать версию - MS SQL 2008 Express и Windows 7. Сработает для него?
12 июн 17, 14:08    [20557944]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4101
AleksVoronezh
Сорри, забыл указать версию - MS SQL 2008 Express и Windows 7. Сработает для него?

Нет.
В Express редакции нет SQL Server Agent.
Но можно сделать это через sqlcmd и Windows Tasks.
12 июн 17, 15:58    [20558164]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Хм.

Сделал на C# простейшую dll, которая может отсылать данные по сети. Проверил ее использованием в другом приложении на C#. Данные на нужный мне адрес и порт приходят. Зарегистрировал ее как пишут в Интернет:

USE cv1;
CREATE ASSEMBLY myCLRFunctions
FROM 'z:\mySplitString.dll'
WITH PERMISSION_SET = SAFE;
go


Потом

Create proc mySplitStringCLR(@input [nchar])
AS EXTERNAL NAME myCLRFunctions.UserDefinedFunctions.tcp_send
go


И наконец
exec mySplitStringCLR 'sarnmiout'

Вывод в SQL Studio "Выполнение команд успешно завершено"


А на приемном устройстве - ничего. Как думаете, в чем может быть дело?
12 июн 17, 20:54    [20558717]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
попробовать что ли WITH PERMISSION_SET = EXTERNAL_ACCESS

Ну не ругайте - последний раз имел дело с MS SQL версии 6.5
12 июн 17, 21:08    [20558738]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36698
AleksVoronezh
Как думаете, в чем может быть дело?
В том, что кто-то в dll не обрабатывает результат вызова функции, "которая может отсылать данные по сети", и не выкидывает его наверх. Поэтому в чем дело могут знать только гадалки на вокзале.

Сообщение было отредактировано: 12 июн 17, 21:39
12 июн 17, 21:38    [20558797]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Заработало (по крайней мере частично) после

USE cv1
GO
EXEC sp_changedbowner 'sa'
ALTER DATABASE database_name SET TRUSTWORTHY ON

USE cv1;
CREATE ASSEMBLY myCLRFunctions
FROM 'z:\mySplitString.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS;
go

Данные уходят, но только та часть, что закомпилированна в dll. Если сделать так:
exec mySplitStringCLR '777777'

То в выводе 777777 отсутсвует. Пожалуй, для начала почищу сервер от всех версий dll.
12 июн 17, 21:51    [20558826]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Все заработало. Тип данных еще откорректировал:

Create proc mySend(@input [nvarchar](128))
AS EXTERNAL NAME myEvent.UserDefinedFunctions.tcp_send
go


Подскажите, пожалуйста - есть таблица в которую добавляются строки.
Как вызвать процедуру mySend 'тут наш текст'

Что бы передать содержимое из нескольких полей вновь добавленной строки?
12 июн 17, 22:35    [20558945]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Кажется понял примерно:


CREATE trigger [dbo].[Test_on_insert] on [dbo].[LogUser] after insert

as

BEGIN

declare @record_new [nvarchar](128)
SET @record_new=(select CONVERT([nvarchar](128),LoginTime,104)+CONVERT([nvarchar](128),LoginTime,108) From inserted)
exec mySend @record_new

End


А интересно.... тут у вас. В базах данных.
12 июн 17, 23:39    [20559066]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
invm
Member

Откуда: Москва
Сообщений: 9128
AleksVoronezh
SET @record_new=(select CONVERT([nvarchar](128),LoginTime,104)+CONVERT([nvarchar](128),LoginTime,108) From inserted)
И благополучно словите ошибку, если в inserted будет больше одной строки.

Самое простое - запаковать в xml. См. документацию на select ... for xml ...

Вам уже писали - такие вещи в триггерах не делают. Предпочитаете убедиться в этом на собственном негативном опыте?
А если уж очень хочется триггером, то нужно асинхронно. Например, через Service Broker.
13 июн 17, 00:38    [20559193]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
invm
AleksVoronezh
SET @record_new=(select CONVERT([nvarchar](128),LoginTime,104)+CONVERT([nvarchar](128),LoginTime,108) From inserted)
И благополучно словите ошибку, если в inserted будет больше одной строки.

Самое простое - запаковать в xml. См. документацию на select ... for xml ...

Вам уже писали - такие вещи в триггерах не делают. Предпочитаете убедиться в этом на собственном негативном опыте?
А если уж очень хочется триггером, то нужно асинхронно. Например, через Service Broker.


Спасибо! Читаю...
13 июн 17, 00:47    [20559205]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3466
AleksVoronezh
invm
пропущено...
И благополучно словите ошибку, если в inserted будет больше одной строки.

Самое простое - запаковать в xml. См. документацию на select ... for xml ...

Вам уже писали - такие вещи в триггерах не делают. Предпочитаете убедиться в этом на собственном негативном опыте?
А если уж очень хочется триггером, то нужно асинхронно. Например, через Service Broker.


Спасибо! Читаю...


Можно сделать курсор и пройтись по всем записям, вызывая на каждой функцию отправки
13 июн 17, 11:44    [20559855]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
invm
Вам уже писали - такие вещи в триггерах не делают. Предпочитаете убедиться в этом на собственном негативном опыте?
А если уж очень хочется триггером, то нужно асинхронно. Например, через Service Broker.


Сорри, без всякого сарказма. А какие тогда вещи делают в триггерах? Чем опасно включение туда действий передачи по сети? Да, тайм-аут значительный при сбоях в сети. Но при этом ведь только затормозит одно пишущее приложение (транзакция?). И, если у меня будет вставляться сразу несколько записей и я запакую все это в XML, при условии нормально работающей сети, какие еще подводные камни Вам видятся?
13 июн 17, 12:01    [20559934]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Спасибо, с курсором интересно. Изучу.
13 июн 17, 12:02    [20559938]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3466
AleksVoronezh
invm
Вам уже писали - такие вещи в триггерах не делают. Предпочитаете убедиться в этом на собственном негативном опыте?
А если уж очень хочется триггером, то нужно асинхронно. Например, через Service Broker.


Сорри, без всякого сарказма. А какие тогда вещи делают в триггерах? Чем опасно включение туда действий передачи по сети? Да, тайм-аут значительный при сбоях в сети. Но при этом ведь только затормозит одно пишущее приложение (транзакция?). И, если у меня будет вставляться сразу несколько записей и я запакую все это в XML, при условии нормально работающей сети, какие еще подводные камни Вам видятся?



как вы будете реагировать на несрабатывание отправки в триггере?

Откатывать всю транзакцию?
Коммитить, но не отправлять?

Например, у меня так: я отправляю в кеш записи, в т.ч. это может быть внешний Redis сервер.
Таймаут - в минимум, но он может конфигурирроваться.
При ошибке отправки я игнорирую эту ошибку, это по определению. Т.е. обработка данных имеет прироритет выше отправки в кеш. Транзакция от этого не зависит.
13 июн 17, 12:26    [20560026]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Приветствую!

>> При ошибке отправки я игнорирую эту ошибку, это по определению. Т.е. обработка данных имеет прироритет выше отправки в кеш. Транзакция от этого не зависит.

Примерно то же самое. В DLL есть секция обработки ошибки отправки, но я ее пока оставил пустой. На практике это выглядит так (вставлял строки из самой утилиты администрирования MS SQL) - утилита при выключенном удаленном устройстве затупливает на время тай-аута в сокетах. Потом запись проходит нормально. Вообще странно, что TCP соединении в том же C# нельзя уменьшить время тай-аута. Люди как-то с этим боролись, кажется, просто сначала создавали а потом убивали процесс по истечение своего времени. И с промежуточным сервером (кешем записи) - это мысль конечно.
13 июн 17, 12:50    [20560096]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
invm
Member

Откуда: Москва
Сообщений: 9128
AleksVoronezh
А какие тогда вещи делают в триггерах?
Те, которые не будут существенно удлиннять транзакцию.
AleksVoronezh
Но при этом ведь только затормозит одно пишущее приложение (транзакция?)
Плюс другие транзакции, которые конкурируют с вашей за доступ к заблокированному ресурсу. Плюс транзакции, конкурирующие с этими, но уже за другие ресурсы. И т.д. и т.п.
13 июн 17, 13:14    [20560181]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49575
Ролг Хупин
как вы будете реагировать на несрабатывание отправки в триггере?

Откатывать всю транзакцию?
Коммитить, но не отправлять?

Не менее интересный вопрос как он вообще будет реагировать на откат транзакции уже после того, как триггер отправил данные.
13 июн 17, 13:43    [20560324]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
В данном случае откатов не бывает - пользователь либо вошел в систему либо нет.
13 июн 17, 14:13    [20560509]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
vlad2016
Member

Откуда:
Сообщений: 13
AleksVoronezh,

Чтобы не "растягивать" триггер используйте UDP. У меня информационные пакеты до 100 байт, отрабатывает без проблем.
13 июн 17, 18:17    [20561492]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
Мы обычно просто сливали данные в некую промежуточную таблицу, а сервис потом сканируя ее выполнял действия над строками, где почту послать, где sms кинуть.
13 июн 17, 18:33    [20561528]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 316
Спасибо, UDP и таблицы вариант!
13 июн 17, 21:53    [20561874]     Ответить | Цитировать Сообщить модератору
 Re: Как из триггера отправить данные по TCP/IP  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3466
AleksVoronezh
Спасибо, UDP и таблицы вариант!


Имхую, что вариант - это засылать из триггера или другого места, где вам хочется сделать отправку, сообщения в очередь брокера и продолжать работать.
А процедура-обработчик будет вынимать и отправлять сообщения в сеть или при ошибке отправки писать какой-то лог и т.д.
14 июн 17, 10:10    [20562576]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить