doutao1282 2017-09-11 12:43
浏览 226
已采纳

SQLite INSERT和SELECT不起作用

simple thing: my code is just not working. Neither INSERT nor SELECT is working in my PDO. Probably I have something wrong, but I'm not a code master, so I need your help.

if (isset($_POST['submit']))
{
try 
    {
        $connection = new PDO('sqlite:../tracker.db');

        $name       = $_POST['name'];
        $unitsize   = $_POST['unitsize'];
        $line       = $_POST['line'];
        $mmr        = $_POST['mmr'];
        $lifespan   = $_POST['lifespan'];
        $connection->exec("INSERT INTO unit (name, unitsize, line, mmr, lifespan) 
        VALUES ('$name', '$unitsize', '$line', '$mmr', '$lifespan')");

        $new_unit = "SELECT unit_id
                     FROM unit
                     ORDER BY unit_id DESC
                     LIMIT 1";
        foreach ($connection->query($new_unit) as $row) {
        $id = $row['unit_id'];
        };

    }
    catch(PDOException $error) 
    {
        echo $error->getMessage();
    }
}

Of course I'm aware that SELECT without records can't work... But my begginer's intuition says, that it could also hava a mistake.

PS: I know, that the code may be a bit messy... sorry for your eyes bleeding :(

EDIT: WHAT I WANT TO ACHIEVE

  1. There is a database tracker.db with existing tables (confirmed by SQLite Browser)
  2. I want to INSERT some data from my form.
  3. After inserting I want to get the last unit_id registered in my DB into variable $id(unit_id is AUTOINCREMENT and PRIMARY KEY)
  4. That's all
  • 写回答

1条回答 默认 最新

  • douzhuan1432 2017-09-11 14:26
    关注

    Well, from looking into your code, I could say that the error (at least one) lie in the following parts:

    • Connection creation.
    • SQL statement - the apostrophs (').
    • Uncatched, failure signalizing, returned values of PDO::exec() or/and PDO::query(). You are using both functions in a proper way regarding their definitions, but maybe they returned FALSE on failure. Situation which you didn't handled at all and which is stated in the "Returned Values" parts of their corresponding docus on php.net.

    So, because the problem with your code was that you didn't know why it didn't work, e.g. you didn't received any error or sign of it, I thought to show you a complete way to use error reporting + prepared statements + validations + exception handling. Please note that all these four elements are mandatory if you want to code a secure and solid PDO solution. More of it, when you are applying them in a proper manner, you'll always know where a problem (or more) lies. And you'll have a lot more efficiency in code writing, because you'll not loose any more time (sometimes hours!) for finding errors.

    Also, how you structure your code is up to you. I presented you here a procedural form, in which you can follow the steps with ease. A better form would be one implemented in an object oriented way.

    Recommendations:

    • Always prepare the sql statements (read this) in order to avoid bad intended db injections. In your case, here, this implies that you must use PDO::prepare() + PDOStatement::execute() instead of PDO::exec (read the "Description" from PDO::exec on php.net).
    • PDO is a very powerfull data access abstraction system. But, in order to use it the right way, you need to always read the documentation for each of its function which you are using, and ESPECIALLY the "Return Values" part. This would be a "must", because there are cases when, on failure, a value can be returned in form of a bool FALSE OR an exception can be thrown. These cases must then be properly handled. For example, in case of PDO::prepare():

    If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling).

    Feel free to ask anything if you have unclarities.

    Good luck.

    <?php
    
    /*
     * Try to include files using statements 
     * only on the top of the page.
     */
    require "../config.php";
    require "../common.php";
    
    /*
     * Set error reporting level and display errors on screen.
     * 
     * =============================================================
     * Put these two lines in a file to be included when you need to
     * activate error reporting, e.g the display of potential errors 
     * on screen.
     * =============================================================
     * Use it ONLY ON A DEVELOPMENT SYSTEM, NEVER ON PRODUCTION !!!
     * If you activate it on a live system, then the users will see
     * all the errors of your system. And you don't want this !!!
     * =============================================================
     */
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
    /*
     * ===================================================
     * Two functions used for automatically binding of the
     * input parameters. They are of course not mandatory, 
     * e.g. you can also bind your input parameters one 
     * by one without using these functions. But then
     * you'd have to validate the binding of each input
     * parameter one by one as well.
     *  
     * Put these two functions in a file to be included,
     * if you wish.
     * ===================================================
     */
    
    /**
     * Get the name of an input parameter by its key in the bindings array.
     *  
     * @param int|string $key The key of the input parameter in the bindings array.
     * @return int|string The name of the input parameter.
     */
    function getInputParameterName($key) {
        return is_int($key) ? ($key + 1) : (':' . ltrim($key, ':'));
    }
    
    /**
     * Get the PDO::PARAM_* constant, e.g the data type of an input parameter, by its value.
     *  
     * @param mixed $value Value of the input parameter.
     * @return int The PDO::PARAM_* constant.
     */
    function getInputParameterDataType($value) {
        if (is_int($value)) {
            $dataType = PDO::PARAM_INT;
        } elseif (is_bool($value)) {
            $dataType = PDO::PARAM_BOOL;
        } else {
            $dataType = PDO::PARAM_STR;
        }
    
        return $dataType;
    }
    
    /*
     * ======================
     * Hier begins your code.
     * ======================
     */
    try {
        // Read from HTTP POST.
        $name = $_POST['name'];
        $unitsize = $_POST['unitsize'];
        $line = $_POST['line'];
        $mmr = $_POST['mmr'];
        $lifespan = $_POST['lifespan'];
    
        // Create a PDO instance as db connection to sqlite.
        $connection = new PDO('sqlite:../tracker.db');
    
        // The sql statement - it will be prepared.
        $sql = 'INSERT INTO unit (
                    name,
                    unitsize,
                    line,
                    mmr,
                    lifespan
                ) VALUES (
                    :name,
                    :unitsize,
                    :line,
                    :mmr,
                    :lifespan
                )';
    
        // The input parameters list for the prepared sql statement.
        $bindings = array(
            ':name' => $name,
            ':unitsize' => $unitsize,
            ':line' => $line,
            ':mmr' => $mmr,
            ':lifespan' => $lifespan,
        );
    
        // Prepare the sql statement.
        $statement = $connection->prepare($sql);
    
        // Validate the preparing of the sql statement.
        if (!$statement) {
            throw new UnexpectedValueException('The sql statement could not be prepared!');
        }
    
        /*
         * Bind the input parameters to the prepared statement 
         * and validate the binding of the input parameters.
         * 
         * =================================================================
         * This part calls the two small functions from the top of the page:
         *  - getInputParameterName()
         *  - getInputParameterDataType()
         * =================================================================
         */
        foreach ($bindings as $key => $value) {
            // Read the name of the input parameter.
            $inputParameterName = getInputParameterName($key);
    
            // Read the data type of the input parameter.
            $inputParameterDataType = getInputParameterDataType($value);
    
            // Bind the input parameter to the prepared statement.
            $bound = $statement->bindValue($inputParameterName, $value, $inputParameterDataType);
    
            // Validate the binding.
            if (!$bound) {
                throw new UnexpectedValueException('An input parameter could not be bound!');
            }
        }
    
        // Execute the prepared statement.
        $executed = $statement->execute();
    
        // Validate the prepared statement execution.
        if (!$executed) {
            throw new UnexpectedValueException('The prepared statement could not be executed!');
        }
    
        /*
         * Get the id of the last inserted row.
         * You don't need to call a SELECT statement for it.
         */
        $lastInsertId = $connection->lastInsertId();
    
        /*
         * Display results. Use it like this, instead of a simple "echo".
         * In this form you can also print result arrays in an elegant
         * manner (like a fetched records list).
         * 
         * Theoretically, this statement, e.g. the presentation of results 
         * on screen, should happen outside this try-catch block (maybe in
         * a HTML part). That way you achieve a relative "separation of 
         * concerns": separation of the fetching of results from the 
         * presentation of them on screen.
         */
        echo '<pre>' . print_r($lastInsertId, TRUE) . '</pre>';
    
        // Close the db connecion.
        $connection = NULL;
    } catch (PDOException $exc) {
        echo '<pre>' . print_r($exc, TRUE) . '</pre>';
        // echo $exc->getMessage();
        // $logger->log($exc);
        exit();
    } catch (Exception $exc) {
        echo '<pre>' . print_r($exc, TRUE) . '</pre>';
        // echo $exc->getMessage();
        // $logger->log($exc);
        exit();
    }
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集