0
我正在寫我的第一個觸發器的MySQL數據庫。觸發器的想法是防止任何人通過measurement_date
插入數據,該數據屬於表中已存在的日期範圍。換句話說,我只希望插入的數據對於表中任何給定的來源具有比最後的measurement_date
更長的日期。MySQL - 表觸發器防止插入表並返回沒有錯誤?
創建觸發器之後,插入數據庫的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.
此觸發器的目標是防止任何人插入數據庫中已存在的測量日期。換句話說,我想阻止插入重複值的OR值與日期落入此源已存在的日期範圍。
爲什麼我的插件使應用程序掛起?我的觸發器有故障。
是的,我雖然關於這種做法。我深信,在MySQL服務器數據庫而不是C#代碼上執行該操作要快得多。我試圖創建某種類型的觸發器來過濾插入的值,以嘗試刪除任何重複的日期值並僅插入新的日期。 –
許多人認爲使用觸發器來實現業務邏輯(這就是你正在做的)是'設計失敗'。我知道你在使用MySQL而不是Oracle,但是設計原則是成立的。谷歌'湯姆吉特與觸發器的麻煩'作了徹底的解釋。 – EdStevens
偉大的文章,我也受到觸發是自切片面包以來最酷的事情的印象。文章解釋了爲什麼不應該把它們用於一切。感謝這個,我想我會走我的問題的代碼路線。謝謝! –