MySQL - 表触发器阻止插入表并返回没有错误?

时间:2016-05-22 17:00:56

标签: c# mysql sql triggers

我正在编写我的第一个触发器MySQL DB。触发器的想法是防止任何人插入具有measurement_date的数据,该数据属于表中已存在的日期范围。换句话说,我只希望插入的数据具有比表中任何给定源的最后measurement_date更晚的日期。

创建触发器后,插入数据库的C#应用​​程序现在挂起,然后在执行插入时最终超时。我使用触发器插入的表的结构如下:

EXPLAIN mydb.water_data;
 _______________________________________________________________
|Field           |Type          |Null   |Key    |Extra          |
----------------------------------------------------------------
|dataID          |int(11)       |NO     |PRI    |auto_increment |
|cond            |int(11)       |YES    |       |               |
|temp            |int(11)       |YES    |       |               |
|measurment_date |datetime      |YES    |       |               |
|sourceid        |varchar(255)  |YES    |MUL    |               |

这是我的触发器:

DELIMITER //
CREATE TRIGGER
    before_insert_waterdata
BEFORE INSERT ON 
    mydb.water_data
FOR EACH ROW
BEGIN
DECLARE last_date DATETIME;
DECLARE message VARCHAR(225);    

SELECT WD.measurment_date 
INTO last_date 
FROM mydb.water_data WD
WHERE WD.sourcbefore_insert_waterdataeID = NEW.measurment_date;

IF (NEW.measurment_date <= last_date) 
THEN 
    SET message = "ERROR: Dataset that is being inserted includes a date range that is already present in the database. Insert aborted.";
    SIGNAL SQLSTATE '45000' SET message_text = message;
END IF;

END;//

我的C#应用​​程序的代码如下:

using (MySqlConnection connection = new MySqlConnection(ConnectionString))
        {
            try
            {
                connection.Open();
                List<string> Rows = new List<string>();

                foreach (var chunk in splitData)
                {
                    StringBuilder sCommand = new StringBuilder("INSERT INTO water_data (cond, temp, measurment_date, sourceid) VALUES ");
                    foreach (var date in chunk)
                    {
                        Rows.Add(string.Format("({0}, {1}, '{2}', '{3}')", MySqlHelper.EscapeString(date.cond.ToString()), MySqlHelper.EscapeString("NULL"), MySqlHelper.EscapeString(date.measurment_date.GetValueOrDefault().ToString("yyyy-MM-dd HH':'mm':'ss", System.Globalization.CultureInfo.InvariantCulture)), MySqlHelper.EscapeString(date.sourceid)));
                    }
                    sCommand.Append(string.Join(",", Rows));
                    sCommand.Append(";");

                    using (MySqlCommand myCmd = new MySqlCommand(sCommand.ToString(), connection))
                    {
                        myCmd.CommandType = CommandType.Text;
                        myCmd.ExecuteNonQuery();  // <------------ The App Crashes right here!!!
                    }
                }
                connection.Close();
            }
            catch(MySqlException ex)
            {
                Debugger.Break();
                ApplicationLog.WriteMessageToLog("ERROR: In Uploader(), There was an error connecting to the database, please check that your connection settings are valid.\n" + ex.Message, true, true, true);
            }

最后,我收到超时错误:

Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

此触发器的目标是防止任何人插入数据库中已存在的测量日期的数据。换句话说,我想防止插入重复值或者日期落在此源已存在的日期范围内的值。

为什么我的插件会使应用程序挂起?我的触发器是否有故障。

1 个答案:

答案 0 :(得分:0)

如果发送的值无效,则表示失败然后重试,因此它会让您在重试之前暂停,然后重试。而不是使用触发器,您可以在代码中进行检查,例如将要输入的值与表中的最大日期进行比较,这将产生相同的结果,但没有任何超时,您还可以修改表ID。