Страница 1 из 1

Вопрос по Event Tag

СообщениеДобавлено: Ср авг 11, 2010 7:04 am
andrew_w2k
Здравствуйте, у меня есть некое значение тэга в хисториан, меняющееся приблизительно раз в пол минуты, хотелось бы реализовать следующее:
по каждому изменению значения тэга выполнять мой SQL запрос.
Пытаюсь реализовать это с помощью Event Tag. Может быть есть какой-нибудь готовый пример или подскажите последовательность действий.

СообщениеДобавлено: Чт авг 12, 2010 5:05 am
Eraser
создайте в БД триггер на данное значение и в нем выполняйте свой запрос

СообщениеДобавлено: Чт авг 19, 2010 9:07 am
andrew_w2k
Eraser писал(а):создайте в БД триггер на данное значение и в нем выполняйте свой запрос

Спасибо. Только MSSQL не позволяет создать триггер над dbo.History

СообщениеДобавлено: Пт авг 20, 2010 6:15 am
Eraser
странно, почему же? прав не хватает? вроде бы триггеры можно создавать над любой таблицей/БД..
ну, может тогда попробовать написать хранимую процедуру, которая будет запускаться по расписанию и сравнивать вычитанное значение из нужного вам столбца со сохраненным ранее в какой то другой табличке, и по результату сравнения, делать нужные вам действия.. громоздко получается, но если результат будет, то почему бы и нет :)

СообщениеДобавлено: Сб авг 21, 2010 4:30 am
beachbear
Повесить триггер на History нельзя, поскольку это не настоящая таблица SQL Server-а, а сами данные идут напрямую в Storage-процесс.

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

Поэтому пока Invensys не проснётся наконец и не переделает Event систему хисториана на PUSH-метод с возможностями легко подцеплять запуск процессов, .NET сборок, и т.д., я бы рекомендовал написать, например, вот такую программу 8) :

Код: Выделить всё
using System;

using System.Data.SqlClient;

using System.Threading;

 

namespace TagChangeDetector

{

    class Program

    {

        private static String GetUserConnectionString()

        {

            SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder();

            sb.DataSource = ".";

            sb.InitialCatalog = "Runtime";

            sb.IntegratedSecurity = true;

            return sb.ToString();

        }

 

        private static void TagChangeDetected(String tagName, String value, DateTime time, Int32 opcQuality, Int32 qualityDetail)

        {

            Console.WriteLine("New value received for tag {0}: {1} {2} {3} {4}",

                tagName, time.ToString("yyyy-MM-dd HH:mm:ss.fff"), value, opcQuality, qualityDetail);               

        }

 

        static void Main(string[] args)

        {

            if (args.Length != 2)

            {

                Console.WriteLine("\nUsage:\n\tTagChangeDetector <tag_name> <polling_interval_in_milliseconds>\n");

                return;

            }

 

            try

            {

                String tagName = args[0];

                Int32  nSleepMilliseconds = Int32.Parse(args[1]);

 

                String   lastKnownValue         = String.Empty;   

                DateTime lastKnownTime          = DateTime.Now;

                Int32    lastKnownOpcQuality    = 0;

                Int32    lastKnownQualityDetail = 0;

 

                using (SqlConnection conn = new SqlConnection(GetUserConnectionString()))

                {

                    conn.Open();

                    using (SqlCommand cmd = conn.CreateCommand())

                    {

                        cmd.CommandText = String.Format(

                            "select DateTime, Value, OPCQuality, QualityDetail from Live where TagName = '{0}'",

                            tagName);

 

                        while (true)

                        {

                            using (SqlDataReader reader = cmd.ExecuteReader())

                            {

                                if (reader.Read())

                                {

                                    String value     = reader["Value"].ToString();   

                                    DateTime time     = (DateTime)reader["DateTime"];

                                    Int32 opcQuality    = (Int32) reader["OPCQuality"];

                                    Int32 qualityDetail = (Int32) reader["QualityDetail"];

 

                                    if (value != lastKnownValue ||

                                        time != lastKnownTime ||

                                        opcQuality != lastKnownOpcQuality ||

                                        qualityDetail != lastKnownQualityDetail)

                                    {

                                        TagChangeDetected(tagName, value, time, opcQuality, qualityDetail);

                                        lastKnownValue         = value;   

                                        lastKnownTime          = time;

                                        lastKnownOpcQuality    = opcQuality;

                                        lastKnownQualityDetail = qualityDetail;

                                    }

                                }

                            }

                            Thread.Sleep(nSleepMilliseconds);

                        }

                    }

                }

            }

            catch (Exception e)

            {

                Console.WriteLine("Error: " + e.Message);

            }

        }

    }

}