IDE + SQL аналог try catch

Интегрованная среда разработки (IDE) промышленных приложений.

IDE + SQL аналог try catch

Сообщение trush05 » Чт сен 02, 2010 10:02 am

Здравствуйте.
В IDE имеется скрипт - добавления и чтения данных из базы данных SQL Server. Скрипт работает но если в БД нет строки удовлетворяющей условию выходит ошибка и скрипт повисает.
В логах SMC выдается следующее:
"SQL.Insert: Script performed an illegal operation.
SQL.Insert: System.Data: Уже существует назначенный этому соединению открытый DataReader, который требуется предварительно закрыть."

Как в IDE можно организовать проверку исключений, на С# это выглядело бы примерно так:
try
{
SqlCommand myCommand = new SqlCommand("select * from table", myConnection);
............
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
trush05
 
Сообщения: 15
Зарегистрирован: Чт сен 02, 2010 9:41 am

Сообщение trush05 » Пт сен 03, 2010 2:31 pm

Отвечу на свой вопрос:

Wonderware Application Server скрипты не поддерживают обработку исключений, как в C # (try catch).
trush05
 
Сообщения: 15
Зарегистрирован: Чт сен 02, 2010 9:41 am

Re: IDE + SQL аналог try catch

Сообщение VOlegL » Чт янв 10, 2013 4:26 pm

можно использовать ArchestrA™ SQLData Script Library User’s Guide
Invensys Systems, Inc.
Revision A

но довольно муторно.
VOlegL
 
Сообщения: 28
Зарегистрирован: Вт апр 01, 2008 4:15 pm

Re: IDE + SQL аналог try catch

Сообщение skom » Сб янв 12, 2013 4:32 pm

А можно посмотреть на скрипт?

Я делал аналогичные скрипты, всё работало без ошибок.
skom
 
Сообщения: 173
Зарегистрирован: Вт окт 02, 2007 5:25 pm

Re: IDE + SQL аналог try catch

Сообщение VOlegL » Пн янв 14, 2013 7:50 pm

Задача: Нужно два раза в год у определенных 1200 объктов из 2500 объктов менять HI.limit и HIHI.limit. Первый раз выставлено вручную. Нужно сохранить уставки текущего периода и залить уставки предыдущего периода.
Пример: Скрипты для сохранения скопированы из руководства стр.21 (Example Scripts) - асинхронный скрипт и асинхронный запрос. Для простоты SQL таблица для сохранения - пустая и у нее 3 поля(tag,hi,hihi). Вставка в SQL таблицу осуществляется одной командой Command.SaveChangesAsync() .
Алгоритм: читаю таблицу и если в ней 0 строк, перебирая нужные объекты добавляю строку. Закончив перебор сбрасываю в SQL таблицу.


Код: Выделить всё
[color=#FF0000]Query Script Code[/color]

DIM Connection as aaDBClient.aaDBConnection;
DIM Command as aaDBClient.aaDBCommand;
'Create a connection object with the connection string.
LogMessage("Creating connection");
Connection = aaDBAccess.CreateConnection("Data Source=xxxxx;Initial Catalog=wond;User Id=yyyy;Password=yyyxxx");
'Create a command object, with a SQL statement.
LogMessage("Creating a command object");
Command = Connection.CreateCommand("Select * from wondSqlTest", aaDBCommandType.SqlStatement, true);
'Everything is ready, let's execute the command async.
LogMessage("Executing command async");
DIM ResultCode as integer;
ResultCode = Command.ExecuteAsync();
if ResultCode <> 0 then
'Failed to start async execution, report the reason.
LogMessage("Got error " + ResultCode + " executing command async");
else
'Execution started, identify the command by ID, for use later.
LogMessage("Command async execution started successfully");
me.CommandID = Command.GetID();
LogMessage("me.CommandID?"+me.CommandID+" successfully");
'Allow the Process script to run.
me.InsertProcessCommand = true;
endif;
'Reset for next time
me.InsertCommand = false;




[color=#BF0000]Process Script Code[/color]

dim xHiLimit as indirect;
dim xHiHiLimit as indirect;
dim s as string;
dim tagnames as string;
dim i as integer;
dim worktag as indirect;
dim strElement as string;
dim strname as string;
DIM Command as aaDBClient.aaDBCommand;
'Retrieve the command object using its ID.
Command = aaDBAccess.GetCommand(me.CommandID);
if Command <> null then
   'Poll for command complete
   if Command.ExecutionState <> aaDBCommandState.Queued then
       LogMessage("Command execution state is " + Command.ExecutionState);
      if Command.ExecutionState == aaDBCommandState.Completed then
         DIM Rows as integer;
         Rows = Command.RowCount;
         LogMessage("Row count returned from command is " + Rows);
         if Rows == 0 then
                     LogMessage("Start object selection" );
                     ‘ Перебор всех объектов
                     for each strElement in MyEngine.Engine.Objects[]
                         ‘ Нужные объекты содержат в имени pk
                         if StringInString( strElement, "pk",1, 0 ) > 0 then
                           strname=strElement+".__Attr_Name_List_1";
                           worktag.BindTo(strname);
                         ‘ Нужные объекты порождены от $pkv или $pkt
                           if StringInString( worktag, "$pkv",1, 0 ) > 0
                              or StringInString( worktag, "$pkt",1, 0 ) > 0  then

                             ' LogMessage("Object is OK!!! - " + strElement);
                               s = strElement+".Temp.Hi.Limit"; xHiLimit.BindTo(s);
                            s = strElement+".Temp.HiHi.Limit"; xHiHiLimit.BindTo(s);
                               ‘ добавляю строку
                               Command.Addrow();
                               ‘ заношу имя tag и лимиты
                               Command.SetCurrentRowColumnByIndex(0,strElement);
                               Command.SetCurrentRowColumnByIndex(1,xHiLimit);
                               Command.SetCurrentRowColumnByIndex(2,xHiHiLimit);
                           endif;
                         endif;
                    next;
                    LogMessage("End object select" );
                    ‘ одной асинхронной командой записываю всю таблицу
                    ‘ следует помнить что, если больше 1000 – нужно изменить параметр в SQLData
                     ‘     
                   DIM ResultCode as integer;
                    ResultCode = Command.SaveChangesAsync();
                   if ResultCode <> 0 then
                      'Failed to start async execution, report the reason.
                       LogMessage("Got error " + ResultCode + " executing command async");
                  endif;   
               endif;
   'When done, dispose the command.
   Command.Dispose();
   'Reset for next time
   me.InsertProcessCommand = false;
   endif;
else
   LogMessage("Cannot find command " + me.CommandID);
   me.InsertProcessCommand = false;
endif;
VOlegL
 
Сообщения: 28
Зарегистрирован: Вт апр 01, 2008 4:15 pm

Re: IDE + SQL аналог try catch

Сообщение skom » Пн янв 14, 2013 8:45 pm

Хм, с aaDBClient я не работал, поэтому помочь не могу, т.к. надо внимательно читать SQLScript.pdf.

Я использовал .NET System.Data.SqlClient.SqlDataReader, например так:

Код: Выделить всё
dim Connection as System.Data.SqlClient.SqlConnection;
dim Command as System.Data.SqlClient.SqlCommand;
dim Reader as System.Data.SqlClient.SqlDataReader;
dim CommandText as string;
dim ConnectionString as string;

Connection = new System.Data.SqlClient.SqlConnection(DBSettings.ConnectionString);
Connection.Open();

CommandText = "SELECT PK_ID FROM Routes";
Command = new System.Data.SqlClient.SqlCommand(CommandText, Connection);
Reader = Command.ExecuteReader();

while Reader.Read()

    b = false;
    for each i in Me.Routes[]
        if Reader("PK_ID") == i then
            b = true;
        endif;
    next;

    if not b then
        IsNew = true;
        if StringLen(NewRoutesList) == 0 then
            NewRoutesList = Reader("PK_ID").ToString();
        else
            NewRoutesList = NewRoutesList + ", " + Reader("PK_ID").ToString();
        endif;
    endif;

endwhile;

Reader.Close();

Connection.Close();
skom
 
Сообщения: 173
Зарегистрирован: Вт окт 02, 2007 5:25 pm

Re: IDE + SQL аналог try catch

Сообщение VOlegL » Пн янв 14, 2013 9:43 pm

Приведенные мной Scripts работают
VOlegL
 
Сообщения: 28
Зарегистрирован: Вт апр 01, 2008 4:15 pm

Re: IDE + SQL аналог try catch

Сообщение ufsergey » Ср апр 09, 2014 3:42 pm

можно на C# написать свою dll и подключить её, затем в скрипте работать только с этой dll. При написании учесть, чтобы методы не выдавали исключения. Если напрямую использовать нетовские классы, то при возникновении исключения скрипт прервётся
ufsergey
 
Сообщения: 44
Зарегистрирован: Пн май 31, 2010 8:50 am

Re:

Сообщение Steelman63 » Чт апр 10, 2014 12:04 am

trush05 писал(а):Отвечу на свой вопрос:
Wonderware Application Server скрипты не поддерживают обработку исключений, как в C # (try catch).


В версии AppServer 2014 наконец-то появился TRY ... CATCH !

Код: Выделить всё
dim command = new System.Data.SqlClient.SqlCommand;
dim reader as System.Data.SqlClient.SqlDataReader;
command.Connection = new System.Data.SqlClient.SqlConnection;

try
 command.Connection.ConnectionString = "Integrated
 Security=SSPI";
 command.CommandText="select * from sys.databases";
 command.Connection.Open();
 reader = command.ExecuteReader();
 while reader.Read()
  me.name = reader.GetString(0);
  LogMessage(me.name);
 endWhile;
catch
 LogMessage(error);
endtry;

if reader <> null and not reader.IsClosed then
 reader.Close();
endif;

if command.Connection.State == System.Data.ConnectionState.Open
then
 command.Connection.Close();
endif;


The error variable is not a string, but a .NET object of System.Exception. This means you can determine the type of exception, even with a simple CATCH statement. Call the GetType() method to determine the exception type, and then perform the operation you want, similar to executing multiple catch blocks.
Steelman63
 
Сообщения: 313
Зарегистрирован: Ср авг 29, 2012 3:42 pm


Вернуться в Development Studio & FactorySuite A&#178;

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7