You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OPCRouter脚本运行报错:Test_Sander无法构建求技术支持

问题:OPC脚本运行时构建失败(编译无错误)

我尝试通过OPC清理并插入数据表(不想购买SQL Server高级版代理),代码编译无错误,但触发运行时出现报错:“Test_Sander”因源码错误无法构建。已尝试一些方法但未能解决,恳请各位提供建议或帮助,如需更多信息请告知,谢谢!

我的代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
// Check if these namespaces are correct and necessary
using inray.OPCRouter.ScriptPlugIn.Shared;
using inray.OPCRouter.ScriptPlugIn.Runtime;
using inray.OPCRouter.ScriptPlugIn.Runtime.Trigger;
using System.Data.SqlClient;

namespace OPCRouter.Script
{
    //public class Test_Sander : ScriptTransferObjectBase
    public class Test_Sander
    {
        private string masterServer = "XXX";
        private string masterDatabase = "MASTER_DB";
        private string prodlogServer = "XXX";
        private string prodlogDatabase = "test";
        private string username = "XXX";
        private string password = "XXX";
        private SqlConnection masterConn;
        private SqlConnection prodlogConn;
        private SqlCommand masterCmd;
        private SqlCommand prodlogCmd;

        // Temporarily change or remove override if not inheriting from ScriptTransferObjectBase
        public void Initialize()
        {
            OpenConnections();
        }

        private void OpenConnections()
        {
            masterConn = new SqlConnection(String.Format("Server={0};Database={1};User Id={2};Password={3};", masterServer, masterDatabase, username, password));
            masterConn.Open();
            masterCmd = masterConn.CreateCommand();

            prodlogConn = new SqlConnection(String.Format("Server={0};Database={1};User Id={2};Password={3};", prodlogServer, prodlogDatabase, username, password));
            prodlogConn.Open();
            prodlogCmd = prodlogConn.CreateCommand();
        }

        private void CloseConnections()
        {
            masterCmd.Dispose();
            masterConn.Close();
            prodlogCmd.Dispose();
            prodlogConn.Close();
        }

        // Temporarily change or remove override if not inheriting from ScriptTransferObjectBase
        public void Write()
        {
            CleanShiftTable();
            CopyRawDataToShift();
        }

        private Tuple<DateTime, DateTime> GetShiftDatetimes(DateTime currentDateTime)
        {
            DateTime shiftStartDateTime, shiftEndDateTime;
            if (currentDateTime.Hour < 6)
            {
                shiftStartDateTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day, 22, 0, 0).AddDays(-1);
                shiftEndDateTime = currentDateTime;
            }
            else if (currentDateTime.Hour < 14)
            {
                shiftStartDateTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day, 6, 0, 0);
                shiftEndDateTime = shiftStartDateTime.AddHours(8);
            }
            else if (currentDateTime.Hour < 22)
            {
                shiftStartDateTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day, 14, 0, 0);
                shiftEndDateTime = shiftStartDateTime.AddHours(8);
            }
            else
            {
                shiftStartDateTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day, 22, 0, 0);
                shiftEndDateTime = currentDateTime;
            }
            return new Tuple<DateTime, DateTime>(shiftStartDateTime, shiftEndDateTime);
        }
        
        
        private void CleanShiftTable()
        {
            try
            {
                string sqlQuery = "DELETE FROM [MASTER_DB].[dbo].[SHIFT]";
                SqlCommand command = new SqlCommand(sqlQuery, masterConn);
                command.ExecuteNonQuery();
                Console.WriteLine("SHIFT table cleaned.");
            }
            catch (SqlException ex)
            {
                Console.WriteLine(String.Format("Error cleaning SHIFT table: {0}", ex.Message));
            }
        }

        private void CopyRawDataToShift()
        {
            try
            {
                DateTime currentDateTime = DateTime.Now;
                var shiftTimes = GetShiftDatetimes(currentDateTime);
                DateTime shiftStartDateTime = shiftTimes.Item1;
                DateTime shiftEndDateTime = shiftTimes.Item2;
            
                string sqlQuery = @"
                INSERT INTO [MASTER_DB].[dbo].[SHIFT] (Timestamp, [Transaction], SerialNr, PN, CustomerNR, Status, Workcenter, Reason, [Return], Recipe, Raw Material, Quantity, OPS_Timestamp, Cycle, Delta_Timestamp)
                SELECT *
                FROM [test].[dbo].[PRODLOG2]
                WHERE Timestamp BETWEEN @shiftStart AND @shiftEnd";
            
                prodlogCmd.Parameters.Clear();  // Clear existing parameters
                prodlogCmd.CommandText = sqlQuery;
                prodlogCmd.Parameters.AddWithValue("@shiftStart", shiftStartDateTime);
                prodlogCmd.Parameters.AddWithValue("@shiftEnd", shiftEndDateTime);
                prodlogCmd.ExecuteNonQuery();
            
                Console.WriteLine("Raw data copied to SHIFT table successfully.");
            }
            catch (SqlException ex)
            {
                Console.WriteLine(String.Format("An error occurred: {0}", ex.Message));
            }
        }
    }
}

核心修复建议

  • 恢复基类继承:OPCRouter脚本插件要求类必须继承ScriptTransferObjectBase,取消注释public class Test_Sander : ScriptTransferObjectBase,并将Initialize和Write方法改为override(基类定义了这些虚方法,必须重写才能被框架识别)。
  • 修复跨库操作的连接错误:CopyRawDataToShift中用连接到test库的prodlogCmd执行插入MASTER_DB的语句,这会导致上下文错误。应改用连接主库的masterCmd执行该SQL。
  • 确保资源释放:CloseConnections方法未被调用,在Write方法末尾或finally块中调用它,避免数据库连接泄漏;同时在CloseConnections中添加Dispose调用彻底释放资源。
  • *避免SELECT 的风险:将SELECT *改为明确列出和INSERT列对应的字段,防止表结构变更导致列数不匹配错误。
  • 完善异常处理:在Initialize方法中添加异常捕获,连接失败时及时抛出异常让框架感知;扩大异常捕获范围,除了SqlException也捕获通用Exception,便于排查构建失败的具体原因。

内容的提问来源于stack exchange,提问作者Sander Vanhemel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:55:55