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
相关产品推荐
相关产品推荐

