gpt4 book ai didi

如果表中存在许可 key ,则 MySQL 代码将用户名和密码插入表中

转载 作者:IT王子 更新时间:2023-10-29 02:09:51 26 4
gpt4 key购买 nike

我正尝试在 golang 中完成一个简单的许可系统,并尝试了多种方法来让它工作。基本上,我在我的数据库中输入了几个随机许可 key ,我的 golang 程序应该检查用户输入的 key 是否存在,如果存在,然后将用户指定的用户名和密码添加到数据库中,以便稍后登录。

这是我没有用过的代码:

"IF EXISTS (SELECT * FROM login WHERE LK = "+reglicenceEntry.Text()+") THEN 
INSERT INTO `login` (`Username`, `Password`, `LK`) VALUES
('"+regusernameEntry.Text()+"', '"+regpasswordEntry.Text()+"', ''); "

这是 golang 错误:

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 'IF EXISTS (SELECT * FROM login WHERE LK = '5qp515YHXEmSDzwqgoJh') THEN INSERT IN' at line 1

非常感谢!

最佳答案

MySQL 语法不支持 IF...THEN 结构,除了在存储的例程和触发器和事件中。参见 https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-compound-statements.html

我为您的代码建议了一个替代解决方案:

INSERT INTO `login` (`Username`, `Password`, `LK`)
SELECT ?, ?, ''
FROM `login`
WHERE `LK` = ?
LIMIT 1

如果您的登录表没有 LK 值,上面的 SELECT 将返回 0 行,因此它不会插入任何内容。

如果你的登录表有 LK 值,上面的 SELECT 将返回至少 1 行(我限制为 1),因此它会插入一行。它插入的行由您的用户名和密码以及 LK 的空白字符串组成。

我展示了参数占位符的使用。您应该在 SQL 中使用参数,而不是将变量连接到查询中。这是避免意外 SQL 注入(inject)的良好做法。参见 http://go-database-sql.org/prepared.html例如。


使用参数的目的是避免SQL注入(inject)问题。请参阅我对 What is SQL injection? 的回答SQL注入(inject)的解释。

或者我的介绍SQL Injection Myths and Fallacies (或 youtube video )。

使用参数时,您需要执行两个步骤。

  • 准备带有占位符 (?) 的查询的第一步,否则您会在其中将变量连接到 SQL 查询中。
  • 第二步是执行准备好的查询,这是你传递变量来填充占位符的时候。

关键是要将变量与您的查询分开,因此如果变量中有任何可能无意中更改您的 SQL 语法的内容(如不平衡的引号),它永远不会与 SQL 结合。做完prepare之后,SQL已经被MySQL服务器解析过了,之后的语法就没法改了。

MySQL 会记住查询的哪些部分需要填写,并且当您在执行步骤中传递变量时,MySQL 会使用您的值填写查询的缺失部分——但这发生在 MySQL 服务器中,而不是在您的服务器中应用。

因此,查询的动态部分(您的变量)与 SQL 语法保持分离,从而避免了 SQL 注入(inject)问题。

对于您在问题中描述的任务,它看起来像这样(我没有测试过这段 Go 代码,但它应该会让您走上正确的道路)。

stmt, err := tx.Prepare("INSERT INTO `login` (`Username`, `Password`, `LK`) SELECT ?, ?, '' FROM `login` WHERE `LK` = ? LIMIT 1")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()

_, err = stmt.Exec(regusernameEntry.Text(), regpasswordEntry.Text(), reglicenceEntry.Text())
if err != nil {
log.Fatal(err)
}

参数的顺序很重要。您传递给 Exec() 的变量的顺序必须与 ? 占位符在您准备好的 SQL 语句中出现的顺序相同。它们由 MySQL 服务器以相同的顺序一对一匹配。

不要在准备好的 SQL 语句中的占位符周围加上引号。这将作为 SQL 中的文字字符串 '?' 工作。使用不带引号的 ? 字符作为占位符。当它在服务器中被 MySQL 合并时,它的工作方式就像您在值周围加上引号一样,就像字符串一样——但没有 SQL 注入(inject)的风险,即使该字符串值包含特殊字符也是如此。

这是另一个提供更多代码示例的站点:https://github.com/go-sql-driver/mysql/wiki/Examples

Exec() 函数用于执行没有结果集的 SQL,如 INSERT、UPDATE、DELETE。 Go SQL 驱动程序中还有其他函数,如 Query()QueryRow() 也接受参数参数。如果您的 SQL 返回结果集,您将使用这些。

关于如果表中存在许可 key ,则 MySQL 代码将用户名和密码插入表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50202694/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com