Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
 Re: Триггер с выводом данных в файл  [new]
_djХомяГ
Guest
глобальные временные таблицы
10 мар 16, 15:08    [18915947]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Laroux
Коллеги, помогите, пожалуйста, сделать триггер на INSERT.

Есть 4 таблицы table1, table2, table3 и table4 (в наличии имеются "кириллические" поля)

Мне необходимо, чтобы по событию добавления новой записи в таблицу table1 в файл на диске выводились данные типа
SELECT * FROM table1
JOIN table2 ON table2.id=table1.id
JOIN table3 ON table3.id=table1.id
JOIN table4 ON table4.id=table1.id
WHERE id={last_insert_id}

Хорошо бы в формате XML (но не критично.. разберу и другой формат)

Пробовал разные варианты с использованием bcp в триггере, но тямы явно не хватает.

Заранее спасибо


Может вы расскажете, что вы в целом пытаетесь сделать, потому что выглядит так, что вы пытаетесь делать что-то очень странное.
10 мар 16, 15:12    [18915962]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
SAMORITYNIN
Laroux,

Это временная таблица, которая видна всему серверу.

Ну, выложу я тебе решение. CMDSHELL, BCP - везде свои ограничения. Начнешь ты резать 50000 файлов и положишь сервак.


msdn global temporary table
10 мар 16, 15:18    [18916010]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
да какой нафиг 50000 файлов? Я ж написал: мне нужна одна единственная строка "джойненная" из 4 таблиц
Всего навсего

Как я не хотел юзать "назначенные задания" для этого, но, видимо, придется.. тупо выбирать каждые пару минут последние пяток записей и засовывать в файл
Другого выхода я не увидел нигде
10 мар 16, 15:19    [18916016]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Laroux
да какой нафиг 50000 файлов? Я ж написал: мне нужна одна единственная строка "джойненная" из 4 таблиц
Всего навсего

Как я не хотел юзать "назначенные задания" для этого, но, видимо, придется.. тупо выбирать каждые пару минут последние пяток записей и засовывать в файл
Другого выхода я не увидел нигде


Я думаю вам надо отправлять сообщения в некую очередь из триггера (Service Broker или таблица-очередь) и на её основе джобой формировать файлы. Потому что работать с файловой системой из триггера это жесть. Вам надо отпустить текущую транзакцию и потом уже отдельно где-то заниматься файловым вводом выводом.
10 мар 16, 15:26    [18916056]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
_хех
Member

Откуда:
Сообщений: 160
Laroux
у меня создается впечатление, что Вы меня просто троллите :) (хотя это может быть и не так)

жизнеспособен ли такой вариант?
create trigger test on table1 
AFTER insert 
as
declare @sql varchar(8000)
TRUNCATE TABLE DataBase.dbo.tempInserted
INSERT INTO DataBase.dbo.tempInserted SELECT * FROM INSERTED
UPDATE DataBase.dbo.tempInserted set field2=(select field2 from DataBase.dbo.table2 where id=(SELECT id FROM INSERTED))
UPDATE DataBase.dbo.tempInserted set field3=(select field3 from DataBase.dbo.table3 where id=(SELECT id FROM INSERTED))
UPDATE DataBase.dbo.tempInserted set field4=(select field4 from DataBase.dbo.table4 where id=(SELECT id FROM INSERTED))
SELECT @sql = 'bcp "select * from DataBase.dbo.tempInserted" queryout C:\Temp\test.txt -c -t -T -S SRV\SQLEXPRESS'
exec xp_cmdshell @sql


нет, у юзера который будет делать инсерт должны быть права на транкейт и смдшелл ....
10 мар 16, 16:12    [18916336]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
_хех
Member

Откуда:
Сообщений: 160
a_voronin
Laroux
да какой нафиг 50000 файлов? Я ж написал: мне нужна одна единственная строка "джойненная" из 4 таблиц
Всего навсего

Как я не хотел юзать "назначенные задания" для этого, но, видимо, придется.. тупо выбирать каждые пару минут последние пяток записей и засовывать в файл
Другого выхода я не увидел нигде


Я думаю вам надо отправлять сообщения в некую очередь из триггера (Service Broker или таблица-очередь) и на её основе джобой формировать файлы. Потому что работать с файловой системой из триггера это жесть. Вам надо отпустить текущую транзакцию и потом уже отдельно где-то заниматься файловым вводом выводом.

+1
автор, совет тебе давали на клр посмотреть ....
10 мар 16, 16:14    [18916347]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Ок.. Давайте перестроим вопрос.
Некое ПО делает в БД новую запись. Мне, собственно говоря, ничего предпринимать (инсертить, апдейтить или т.п.) с этим не надо.

Мне нужна эта новая запись в виде файлика. Кто-то тут писал, что я делаю нечто странное: не сказал бы. Мне просто надо эти же данные дублировать на внешний хостинг (Apache+PHP+MySQL) - вот и всех делов.

Вы мне предлагаете где-то отдельно заниматься файловым выводом. Как я его его инициирую и где?

Пробежал глазками по SQL CLR: "технология позволяет расширять функциональность SQL сервера с помощью .NET языков, например C# или VB.NET"
Вопрос 1: эта технология позволит мне отследить появление новой записи в таблице?
Вопрос 2: или не вопрос - разбираться с каким-нить языком придется. С тем же C# или VB.NET. Для одной задачи как-то прямо не айс.
10 мар 16, 16:38    [18916499]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Glory
Member

Откуда:
Сообщений: 104760
Laroux
Пробежал глазками по SQL CLR: "технология позволяет расширять функциональность SQL сервера с помощью .NET языков, например C# или VB.NET"
Вопрос 1: эта технология позволит мне отследить появление новой записи в таблице?

CLR всего лишь позволяет писать дополнительный функционал не на TSQL, а на C# или VB.NET
А у вас проблема с пониманием того, как организовать взаимодействие двух процессов.

Самый простой способ, это изменить процесс, которым "Некое ПО делает в БД новую запись. ". Чтобы _после_ "делания новой записи" выполнились еще какие-то команды/процедуры

Если это невозможно, то триггер ваш должен запускать какой-то _асинхронный процесс_. Потому что любой синхронный процесс, запущенный в триггере, упрется в блокировки

Думайте над этим
10 мар 16, 16:46    [18916543]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Ковырялся, ковырялся.. наковырял пока вот что:
у меня корректно срабатывает триггер типа
USE [TBD]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[tester] 
   ON  [TBD].[dbo].[tINT]
   AFTER INSERT
AS 
BEGIN
	declare @sql varchar(8000)
	SET NOCOUNT ON;
	SELECT @sql = 'bcp "SELECT TOP 1 * from [TBD].[dbo].[tINT] WITH (NOLOCK) ORDER By id DESC;"  queryout C:\Temp\test.txt -C RAW -c -t ### -T -S CR\CPCC'
	exec xp_cmdshell @sql
END
т.е. WITH (NOLOCK) малость выровнял ситуацию и, по крайне мере, из одной таблицы данные выводятся корректно.

Попозже попробую с джойнами.. посмотрим, что выйдет
10 мар 16, 17:56    [18916814]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Laroux
Ковырялся, ковырялся.. наковырял пока вот что:
у меня корректно срабатывает триггер типа
USE [TBD]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[tester] 
   ON  [TBD].[dbo].[tINT]
   AFTER INSERT
AS 
BEGIN
	declare @sql varchar(8000)
	SET NOCOUNT ON;
	SELECT @sql = 'bcp "SELECT TOP 1 * from [TBD].[dbo].[tINT] WITH (NOLOCK) ORDER By id DESC;"  queryout C:\Temp\test.txt -C RAW -c -t ### -T -S CR\CPCC'
	exec xp_cmdshell @sql
END
т.е. WITH (NOLOCK) малость выровнял ситуацию и, по крайне мере, из одной таблицы данные выводятся корректно.

Попозже попробую с джойнами.. посмотрим, что выйдет


Читать незакоммиченные данные с помощью BCP, которая запущена из триггера с помощью xp_cmdshell... Ахтунг!!! Архтунг!!! На сервере работает мегархитектор.

Картинка с другого сайта.
10 мар 16, 18:12    [18916867]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
добавь stamp, джобой формируй файл по сохранённому стемпу

а вообще...
Laroux
Ок.. Давайте перестроим вопрос.
данные дублировать на внешний хостинг (Apache+PHP+MySQL) - вот и всех делов.

может есть прямее путь?
10 мар 16, 18:21    [18916903]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
a_voronin
Читать незакоммиченные данные с помощью BCP, которая запущена из триггера с помощью xp_cmdshell... Ахтунг!!! Архтунг!!! На сервере работает мегархитектор.
Да, я не спец в MS SQL, господа. Иначе бы не задавал здесь тупых вопросов. Я потому и пришел сюда - с надеждой, что мне помогут.
Я не понимаю что значит "незакоммиченные"..
Меня совершенно не смущает запуск xp_cmdshell из триггера, о котором я и узнал то, собственно, занявшись реализацией задумки.


TaPaK
добавь stamp, джобой формируй файл по сохранённому стемпу
что такое stamp? Джоб какой? виндовый или сиквельный? Прокатит ли с Express версией SQL-сервера?

TaPaK
может есть прямее путь?
я готов к продуктивному диалогу. У меня других идей просто нет. Подскажете? буду благодарен

Парни, без обид.. Я достаточно подробно описал свою, как я думаю, не сложную для более-менее профессионала задачу. И пока я не увидел ни одного совета, который бы мне помог. Кроме, двух вещей, которые мне стали понятны:
первое
Glory
Вариантов вывода результатов запроса вовне всего один - клиентская программа.

обратите внимание - один единственный вариант!
и второе
Glory
Запуск bcp через xp_cmdshell создает свое соединение к серверу.
В котором нельзя просто так прочитать данные, которые заблокированы вашей транзакцией, которая ждет окончания триггера, который запустил bcp, которая в другом коннекте ждет окончания блокировки, которые создала ваша транзакция ...


Возможно были еще дельные советы, но сформулированы они так, что я даже не могу понять, как их нагуглить, а не то, что реализовать.
Опишите мне адекватный более-менее понятный алгоритм реализации задачи, пожалуйста. А не засаживайте на ровном месте
10 мар 16, 22:17    [18917634]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Активист
Member [заблокирован]

Откуда: 56233
Сообщений: 51
Laroux,

Сделайте FILESTREAM таблицу типо и пишите в нее из триггера. Каждая новая строка будет представлена файлом в директории ProdFILES_FS. Папку - мониторить и перекидывать новые файлы куда нужно. В последствии папку можно почистить нетранзакционно командой FS. =)

+
CREATE TABLE [dbo].[FW_Files](
	[FileID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
	[FileData] [varbinary](max) FILESTREAM  NULL,
 CONSTRAINT [PK_FW_Files] PRIMARY KEY CLUSTERED 
(
	[FileID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] FILESTREAM_ON [Vision_ProdFILES_FS]
) ON [PRIMARY] FILESTREAM_ON [ProdFILES_FS]
10 мар 16, 23:19    [18917823]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Спасибо.. но пошел в гугл и первое, что читаю
гугл
FileStream впервые появился в MS SQL 2008
а у меня, сцукко, 2005
10 мар 16, 23:32    [18917862]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Newbie001
Member

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

Используйте Service Broker - сделайте очередь, из триггера в нее пишите id новых/измененных строк. А в обработчике очереди, зная id строк, клейте из них XML/кидайте в файлы/передавайте веб-сервисам и т.д.
Смысл в том, чтобы все длительные операции из триггера убрать.

И вывод в файл вам не нужен. Конечная цель какая, положить данные в Mysql? Тогда можно написать хранимую процедуру на sqlclr, в которую передавать все нужные данные например в виде xml, а внутри хп подключаться к mysql и передавать xml с данными ему.

Гуглить по словам "ms sql service broker example"
10 мар 16, 23:32    [18917863]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Newbie001
Member

Откуда:
Сообщений: 27
Либо вообще настроить linked server на mysql и прямо из триггера заливать данные в целевые таблицы.
10 мар 16, 23:38    [18917879]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
так они у меня в разных местах :)
сиквел в офисе в серверной стоит, а сайт - у хостинг-провайдера

Ладно, хорош изысканий, наверное.. Завтра опробую следующую схему: сделаю "левую" таблицу. Триггером буду лить в нее инсерты. А в левой таблице сделаю еще один триггер, который с помощью bcp с конструкцией WIDTH (NOLOCK) будет выбрасывать строки в файл
Пусть и выглядит как демотиватор a_voronin-а.. мне побоку. Главное, чтобы работало
10 мар 16, 23:49    [18917906]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Newbie001
Member

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

А какой смысл в этой второй таблице? Оставляйте как есть.
Возможно быстрее будет выгружать в файл через sqlclr, но это надо проверять.
10 мар 16, 23:55    [18917920]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Может и нет смысла. Просто мне надо не из одной таблицы вываливать данные, а заджойниться с + еще тремя таблицами, в которые так же добавляются строки с теми же id (ключами).
Что-то не уверен, что bcp осилит. Но попробую
10 мар 16, 23:58    [18917929]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Newbie001, SQLCLR надо учить же еще :) там же надо на каком-нить VB писать. А я ток PHP знаю
10 мар 16, 23:59    [18917930]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Glory
Member

Откуда:
Сообщений: 104760
Laroux
Пусть и выглядит как демотиватор a_voronin-а.. мне побоку. Главное, чтобы работало

С таким подходом демотиватор a_voronin-а будет выглядеть лучшим решением
11 мар 16, 09:06    [18918317]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Laroux
Member

Откуда:
Сообщений: 57
Glory, у меня в этой БД происходит от 30 до 90 инсёртов в месяц. В лучшем случае до 200.
Это я к тому, что это не высоконагруженная какая-то очень сложная система.

Исходя из этого, чем мне грозит использование описанного мной варианта выгрузки данных?
Что-то нарушится? Может какие-то проблемы с безопасностью? Или ... что?
11 мар 16, 09:20    [18918360]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
Glory
Member

Откуда:
Сообщений: 104760
Laroux
Glory, у меня в этой БД происходит от 30 до 90 инсёртов в месяц. В лучшем случае до 200.
Это я к тому, что это не высоконагруженная какая-то очень сложная система.

Понимате говнокод - он везде говнокод. В любой системе.

Laroux
Исходя из этого, чем мне грозит использование описанного мной варианта выгрузки данных?
Что-то нарушится? Может какие-то проблемы с безопасностью? Или ... что?

Вам лично - ничем не грозит в данном случае.
11 мар 16, 09:28    [18918387]     Ответить | Цитировать Сообщить модератору
 Re: Триггер с выводом данных в файл  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Laroux
Glory, у меня в этой БД происходит от 30 до 90 инсёртов в месяц. В лучшем случае до 200.
Это я к тому, что это не высоконагруженная какая-то очень сложная система.

Исходя из этого, чем мне грозит использование описанного мной варианта выгрузки данных?
Что-то нарушится? Может какие-то проблемы с безопасностью? Или ... что?


Для начала вам надо понять, что написали пол-ную х...ню.

В триггере не завершена транзакция, поэтому другая транзакция (сессия) запись не видит, если только вы не задействовали NOLOCK , то есть приказали читать грязные данные, то есть данные, которые ещё не факт, что останутся в базу, например, если кто-то отменит транзакцию.

Во-вторых, Вы не слушаете, что вам говорят. Даже Glory уже употребил термин "гавнокод".

Я вам сказал, что делать -- скинуть из триггера ID в некую буферную таблицу, а потом из другого процесса, читать эту таблицу (читать только закоммиченные записи) и выгружать данные в ваш файл. Вот там можете свой cmdshell пускать.

Самое грамотное решение -- это Service Broker, но вам лучше за него пока не браться.
11 мар 16, 11:53    [18919093]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить