[英]Creating a MySQL stored procedure to update records
我正在轉換所有現有的 MSSQL 數據庫,並且存儲過程卡在一個新的存儲過程中,我需要更新現有記錄。 一旦將記錄插入數據庫並成功發送電子郵件(或至少傳遞到 SMTP 服務器),就會從 Web 表單調用該過程
我在 MSSQL 中有一個工作程序很長一段時間了,但我正在嘗試將其轉換為 MySQL。 我傳入了 3 個變量 - 一點表示電子郵件已發送,一個字符串表示已使用哪個 SMTP 服務器發送電子郵件和一個唯一的記錄 ID,以便我知道要更新的記錄。 我還將日期和時間添加到另一個字段以了解程序何時運行。
我有以下內容,但不斷收到錯誤消息“#1064 - 您的 SQL 語法有錯誤;請檢查與您的 MySQL 服務器版本相對應的手冊,以獲取在第 7 行附近使用的正確語法 - 但我沒有在第 7 行看不到任何東西 - 至少在我看來。
我嘗試使用的代碼是:
CREATE PROCEDURE `sp_Test`(
`emailSent_In` BIGINT UNSIGNED,
`emailTransport_In` VARCHAR(100),
`formSecret_In` VARCHAR(32)
)
BEGIN
SET @`query` := CONCAT('UPDATE ',`tbl_JustSayThanks`,'
SET `emailSent` = `emailSent_In`,
`emailTransport` = ',`emailTransport_In`,',
`emailSentDate` = NOW()
WHERE `formSecret` = ', `formSecret_In`, '');
PREPARE `stmt` FROM @`query`;
EXECUTE `stmt`;
@`query` := NULL;
DEALLOCATE PREPARE `stmt`;
END//
DELIMITER ;
僅供參考,我正在使用基於我從 wchiquito 收到的先前答案的 CONCAT,最終將傳入表名。 但是,在去那里之前,我想讓它在簡化的級別上工作。
以下是錯誤的:
SET @`query` := CONCAT('UPDATE ',`tbl_JustSayThanks`,'
因為您似乎將 SQL 文本與tbl_JustSayThanks
的值連接tbl_JustSayThanks
,但我認為您的意思是使用標識符本身。 因此,這應該是:
SET @`query` := CONCAT('UPDATE `tbl_JustSayThanks`',
以下是錯誤的:
`emailTransport` = ',`emailTransport_In`,',
因為該變量是一個 VARCHAR,但您沒有在 SQL 語句中將其作為字符串文字引用。 很容易與多個級別的引用混淆。 應該是:
`emailTransport` = ''', `emailTransport_In`, ''',
出於同樣的原因,以下是錯誤的:
WHERE `formSecret` = ', `formSecret_In`, '');
應該是:
WHERE `formSecret` = ''', `formSecret_In`, '''');
這仍然會遇到 SQL 注入問題,除非您可以保證輸入參數是安全的(這不是一個好的假設)。 如果需要將值連接到 SQL 表達式中,則應使用QUOTE()
函數進行轉義:
SET @query = CONCAT('
UPDATE tbl_JustSayThanks
SET emailSent = ', QUOTE(emailSent_In), '
emailTransport = ', QUOTE(emailTransport_In), '
emailSentDate = NOW()
WHERE formSecret = ', QUOTE(formSecret_In));
更多評論:
?
占位符,而不是將變量連接到 SQL 字符串中。 您不要在 SQL 查詢中引用參數占位符。 這樣您就不會遇到像您發現的那樣難以調試的語法錯誤。這是一個顯示修復程序的示例:
CREATE PROCEDURE sp_Test(
emailSent_In BIGINT UNSIGNED,
emailTransport_In VARCHAR(100),
formSecret_In VARCHAR(32)
)
BEGIN
SET @query = '
UPDATE tbl_JustSayThanks
SET emailSent = ?,
emailTransport = ?,
emailSentDate = NOW()
WHERE formSecret = ?';
SET @es = emailSent_In;
SET @et = emailTransport_In;
SET @fs = formSecret_In;
PREPARE stmt FROM @query;
EXECUTE stmt USING @es, @et, @fs;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
最后評論:
這就是我真正編寫程序的方式:
CREATE PROCEDURE sp_Test(
emailSent_In BIGINT UNSIGNED,
emailTransport_In VARCHAR(100),
formSecret_In VARCHAR(32)
)
BEGIN
UPDATE tbl_JustSayThanks
SET emailSent = emailSent_In,
emailTransport = emailTransport_In,
emailSentDate = NOW()
WHERE formSecret = formSecret_In;
END//
DELIMITER ;
您還應該知道 MySQL 存儲過程遠不如 Microsoft SQL Server。 MySQL 不保留已編譯的存儲過程,它不支持包,它沒有調試器...我建議您不要使用 MySQL 存儲過程。 請改用應用程序代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.