[英]Creating a MySQL stored procedure to update records
I'm converting all of my existing MSSQL databases and stored procedures am stuck on a new stored procedure where I need to update an existing record.我正在转换所有现有的 MSSQL 数据库,并且存储过程卡在一个新的存储过程中,我需要更新现有记录。 The procedure gets called from a web form once a record has been inserted into the database and en email sent successfully (or at least passed off to the SMTP server)
一旦将记录插入数据库并成功发送电子邮件(或至少传递到 SMTP 服务器),就会从 Web 表单调用该过程
I've had a working procedure in MSSQL for a long time but am trying to convert it to MySQL.我在 MSSQL 中有一个工作程序很长一段时间了,但我正在尝试将其转换为 MySQL。 I'm passing in 3 variables - a bit indicating the email got sent, a string indicating which SMTP server has been used to sent the email and a unique record id so I'll know what record to update.
我传入了 3 个变量 - 一点表示电子邮件已发送,一个字符串表示已使用哪个 SMTP 服务器发送电子邮件和一个唯一的记录 ID,以便我知道要更新的记录。 I'm also adding the date and time to another field to know when the procedure ran.
我还将日期和时间添加到另一个字段以了解程序何时运行。
I've got the following but keep getting an error "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 7 - yet I don't see anything off at line 7 - at least to my eye.我有以下内容,但不断收到错误消息“#1064 - 您的 SQL 语法有错误;请检查与您的 MySQL 服务器版本相对应的手册,以获取在第 7 行附近使用的正确语法 - 但我没有在第 7 行看不到任何东西 - 至少在我看来。
The code I'm trying to use is:我尝试使用的代码是:
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 ;
Just FYI, I'm using the CONCAT based on a previous answer I received from wchiquito and will be passing in the table name eventually.仅供参考,我正在使用基于我从 wchiquito 收到的先前答案的 CONCAT,最终将传入表名。 But, I wanted to get it to work on a simplified level before going there.
但是,在去那里之前,我想让它在简化的级别上工作。
The following is wrong:以下是错误的:
SET @`query` := CONCAT('UPDATE ',`tbl_JustSayThanks`,'
because you seem to be concatenating your SQL text with the value of tbl_JustSayThanks
, but I think you mean to use the identifier itself.因为您似乎将 SQL 文本与
tbl_JustSayThanks
的值连接tbl_JustSayThanks
,但我认为您的意思是使用标识符本身。 This should therefore be:因此,这应该是:
SET @`query` := CONCAT('UPDATE `tbl_JustSayThanks`',
The following is wrong:以下是错误的:
`emailTransport` = ',`emailTransport_In`,',
because the variable is a VARCHAR but you don't quote it as a string literal in your SQL statement.因为该变量是一个 VARCHAR,但您没有在 SQL 语句中将其作为字符串文字引用。 It's easy to get mixed up with the multiple levels of quoting.
很容易与多个级别的引用混淆。 It should be:
应该是:
`emailTransport` = ''', `emailTransport_In`, ''',
The following is wrong for the same reason:出于同样的原因,以下是错误的:
WHERE `formSecret` = ', `formSecret_In`, '');
it should be:应该是:
WHERE `formSecret` = ''', `formSecret_In`, '''');
This still suffers from SQL injection problems, unless you can guarantee that the input parameters are safe (which is not a good assumption).这仍然会遇到 SQL 注入问题,除非您可以保证输入参数是安全的(这不是一个好的假设)。 If you need to concatenate values into your SQL expressions, you should use the
QUOTE()
function to do escaping:如果需要将值连接到 SQL 表达式中,则应使用
QUOTE()
函数进行转义:
SET @query = CONCAT('
UPDATE tbl_JustSayThanks
SET emailSent = ', QUOTE(emailSent_In), '
emailTransport = ', QUOTE(emailTransport_In), '
emailSentDate = NOW()
WHERE formSecret = ', QUOTE(formSecret_In));
More comments:更多评论:
?
?
placeholders, intead of concatenating variables into the SQL string. Here's an example showing the fixes:这是一个显示修复程序的示例:
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 ;
Final comment:最后评论:
This is how I'd really write the procedure:这就是我真正编写程序的方式:
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 ;
You should also be aware that MySQL stored procedures are greatly inferior to Microsoft SQL Server.您还应该知道 MySQL 存储过程远不如 Microsoft SQL Server。 MySQL doesn't keep compiled stored procedures, it doesn't support packages, it doesn't have a debugger... I recommend you do not use MySQL stored procedures.
MySQL 不保留已编译的存储过程,它不支持包,它没有调试器...我建议您不要使用 MySQL 存储过程。 Use application code instead.
请改用应用程序代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.