doutong1890 2018-05-06 17:37
浏览 110
已采纳

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

I am trying to accomplish a simple licensing system in golang and have tried numerous ways to get it to work. Basically, I have input a couple of random licensing keys into my database and my golang program should check to see if the user-input key exists and if it does then add the user specified username and password into the database to login later.

This is the code that I have that hasn't been working:

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

This is the golang error:

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

Thanks so much!

  • 写回答

1条回答 默认 最新

  • douqian4411 2018-05-06 18:11
    关注

    MySQL syntax doesn't support IF...THEN constructs except within stored routines and triggers and events. See https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-compound-statements.html

    I suggest an alternative solution for your code:

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

    If your login table does not have the LK value, the SELECT above will return 0 rows, therefore it will not insert anything.

    If your login table has the LK value, the SELECT above will return at least 1 row (and I limit it to 1), therefore it will insert a row. The row it inserts is comprised of your username and password, and a blank string for the LK.

    I showed use of parameter placeholders. You should use parameters in SQL instead of concatenating variables into your query. This is good practice to avoid accidental SQL injection. See http://go-database-sql.org/prepared.html for examples.


    The purpose of using parameters is to avoid SQL injection problems. See my answer to What is SQL injection? for an explanation of SQL injection.

    Or my presentation SQL Injection Myths and Fallacies (or youtube video).

    When using parameters, you do two steps.

    • The first step to prepare a query with placeholders (?) where you would otherwise concatenate variables into your SQL query.
    • The second step is to execute the prepared query, and this is the time you pass the variables to fill in the placeholders.

    The point is to keep variables separate from your query, so if there's anything in the variable that could unintentionally change your SQL syntax (like imbalanced quotes), it is never combined with the SQL. After you do the prepare, the SQL has already been parsed by the MySQL server, and there's no way to change the syntax after that.

    MySQL remembers which parts of the query need to be filled in, and when you pass variables during the execute step, MySQL fills in the missing parts of the query using your values — but this happens within the MySQL server, not in your application.

    Thus the dynamic parts of the query — your variables — are kept separate from the SQL syntax and you avoid SQL injection problems.

    For your task described in your question, it would look something like this (I have not tested this Go code, but it should put you on the right path).

    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)
    }
    

    The order of parameters is important. The variables you pass to Exec() must be in the same order that the ? placeholders appear in your prepared SQL statement. They are matched up, one for one, in the same order, by the MySQL server.

    Do not put quotes around the placeholders in your prepared SQL statement. That will work as a literal string '?' in SQL. Use an unquoted ? character for a placeholder. When it gets combined by MySQL in the server, it will work as if you had put quotes around the value like a string — but with no risk of SQL injection even if that string value containing special characters.

    Here's another site that gives more code examples: https://github.com/go-sql-driver/mysql/wiki/Examples

    The Exec() function is for executing SQL that has no result set, like INSERT, UPDATE, DELETE. There are other functions in the Go SQL driver like Query() and QueryRow() that also accept parameter arguments. You'd use these if your SQL returns a result set.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R
  • ¥15 在线请求openmv与pixhawk 实现实时目标跟踪的具体通讯方法
  • ¥15 八路抢答器设计出现故障
  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档