我准备好的陈述有啥问题?

Posted

技术标签:

【中文标题】我准备好的陈述有啥问题?【英文标题】:What is wrong with my prepared statement?我准备好的陈述有什么问题? 【发布时间】:2021-02-17 08:34:47 【问题描述】:

在使用似乎无法追踪的准备好的语句时,我的 SQL 语法出现错误。我已经大大简化了代码,但错误仍然存​​在。这是我第一次尝试准备好的陈述,所以它可能是相当基本的东西,但谷歌仍然没有帮助我。我想要做的是用一组参数更新一个表,我在变量中交出这些参数(在给定的例子中,我用一个简单的“4”(不在变量中)替换了这组参数,并且只交出参数选择行作为变量)。代码如下:

SQLcommand.CommandText = "PREPARE my_prep_statement FROM 'UPDATE tbl1 SET status = 4 WHERE Number =  ?';"
SQLcommand.ExecuteNonQuery()
SQLcommand.Parameters.AddWithValue("@DosiNr", "123")
SQLcommand.CommandText = "EXECUTE my_prep_statement USING @DosiNr;"
SQLcommand.ExecuteNonQuery()

列 Number 的类型为 varchar(8)。 错误消息为“您的 SQL 语法有错误;请检查与您的 mysql 服务器版本相对应的手册,以获取正确的语法,以便在第 1 行的 ''123'' 附近使用”并且我的表没有更新.

我正在使用 mySQL 数据库,服务器版本 5.1.41

我有一种强烈的感觉,就是在这里看不到非常简单的东西,但我需要帮助来发现它:-(

非常感谢!!

【问题讨论】:

您提到了一个错误,但没有说明错误是什么。你有例外吗?如果是这样,正在显示什么消息?如果没有,会发生什么?另外,请为您正在使用的特定 SQL 数据库产品添加标签。 哦,对不起!我更新了我的问题 - 希望现在清楚了吗? 提供完整且不变的错误消息文本,而不是关于它的故事。 我只省略了被告知要检查手册的部分,但我发现发布不完整的错误消息是多么令人困惑,我在我的帖子中修复了这个问题。 但是,将准备好的语句中的?替换为@DosiNr会导致完全相同的错误消息。此外,在执行语句中写入值 '123' 而不是 @DosiNr 会给出相同的错误消息。如果准备好的语句中的?不是通配符(也可以用于@DosiNr等用户变量),那么我必须回去学习准备好的语句的基础知识——请告诉我这是否是我所拥有的去做! 【参考方案1】:

使用 API 中的预处理语句时,您不使用 SQL PREPARE 语法,而是使用特定的 API 函数。对于.Net,它是SqlCommand.Prepare

documentation 提供了一个很好的例子。

【讨论】:

非常感谢@rveerd,与.Prepare 合作解决了我的问题!! :) 我自己不会到那里!【参考方案2】:

您不能提供文字作为准备好的语句参数,只允许使用 UDV,请参阅EXECUTE Statement。将您的值设置为用户定义的变量,然后使用此变量执行语句。 在 SQL 中看起来像

PREPARE my_prep_statement FROM 'UPDATE tbl1 SET status = 4 WHERE Number =  ?';
SET @var := 123;
EXECUTE my_prep_statement USING @var;

所以你需要类似的东西

SQLcommand.CommandText = "PREPARE my_prep_statement FROM 'UPDATE tbl1 SET status = 4 WHERE Number =  ?';"
SQLcommand.ExecuteNonQuery()
SQLcommand.CommandText = "SET @var := @DosiNr;"
SQLcommand.Parameters.AddWithValue("@DosiNr", "123")
SQLcommand.ExecuteNonQuery()
SQLcommand.CommandText = "EXECUTE my_prep_statement USING @var;"
SQLcommand.ExecuteNonQuery()

@var 可能会被 VB.Net 视为未设置值的查询参数,并出现相应的错误...如果是这样,我不知道该怎么处理这个问题。

【讨论】:

感谢您指出我一直忽略 UDV 和参数之间的区别!但是,命令SET @var := @DosiNr; 会抛出一个致命错误“在命令执行期间遇到致命错误” ...当我在SET @var := @DosiNr 之前执行.parameters.addwithvalue("@DosiNr", "123") 时也会发生同样的情况 好的,现在我找到了内部异常。它说“必须定义参数'@var'”。我觉得我在绕圈子。 Akina,您对此还有什么想法吗? @sarah 请阅读我回答的最后一句话。 PS。我知道这个问题是可以解决的...尝试通过错误信息文本和VB标签搜索SO。 谢谢你,Akina! :) (我读了那句话,但仍然希望 mysql 而不是 vb 导致该异常)

以上是关于我准备好的陈述有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

我需要坚持准备好的陈述吗?

PDO准备好的陈述[关闭]

什么是准备好的陈述?

PHP 准备好的陈述:阅读

准备好的陈述:阅读

PHP:使用准备好的语句进行注入保护