top-think / framework

ThinkPHP Framework
http://www.thinkphp.cn
Other
2.72k stars 1.06k forks source link

好多坑,数据库驱动 #373

Closed AndyYuenOk closed 7 years ago

AndyYuenOk commented 7 years ago

查询字段为数据库关键字的时候比如字段为group,model就会出错,组装sql语句的时候不会加上 ` 引号

liu21st commented 7 years ago

给出你的用法以及TP版本

AndyYuenOk commented 7 years ago

"name": "topthink/framework", "version": "v5.0.3", 修改之前SELECT DISTINCT group FROM menu WHERE group <> '' AND pid = '68' 报错 修改之后[ sql ] [ SQL ] SELECT DISTINCT group FROM menu WHERE group <> '' AND pid = '68' [ RunTime:0.000100s ]

liu21st commented 7 years ago

我的意思是给出 你的查询用法 不是sql语句

AndyYuenOk commented 7 years ago

sqlite3

DROP TABLE IF EXISTS `config`;
CREATE TABLE `config` (
  `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, -- 配置ID
  `name` varchar(30) NOT NULL DEFAULT '' UNIQUE, -- 配置名称
  `type` tinyint(3) NOT NULL DEFAULT '0', -- 配置类型
  `title` varchar(50) NOT NULL DEFAULT '', -- 配置说明
  `group` tinyint(3) NOT NULL DEFAULT '0', -- 配置分组
  `extra` varchar(255) NOT NULL DEFAULT '', -- 配置值
  `remark` varchar(100) NOT NULL DEFAULT '', -- 配置说明
  `create_time` int(10) NOT NULL DEFAULT '0', -- 创建时间
  `update_time` int(10) NOT NULL DEFAULT '0', -- 更新时间
  `status` tinyint(4) NOT NULL DEFAULT '0', -- 状态
  `value` text, -- 配置值
  `sort` smallint(3) NOT NULL DEFAULT '0' -- 排序
);

use think\Db;

class Index
{
    public function index()
    {
         Db::name('Config')
            ->where(['group' => 1])
            ->select();
    }
}
momoca commented 7 years ago
        echo \think\Db::name('Config')
            ->where(['`group`' => 1])
            ->select(false);

结果:SELECT * FROMconfigWHEREgroup= 1 对于这种特殊的表名字段名请自行加上反引号即可.

AndyYuenOk commented 7 years ago

比如config model这样呢

        $data = Request::instance()->post();

        /* 获取数据对象 */
        $status = $this->allowField(true)->save($data);

如果自行加引号就会报错

momoca commented 7 years ago
$data = Request::instance()->post();
$data['`group`']=$data['group'];
unset($data['group']);
...
liu21st commented 7 years ago

不需要使用反引号,驱动会自动处理的啊

momoca commented 7 years ago

以 @liu21st 的为准.

AndyYuenOk commented 7 years ago

手册这么写 但是这并不是我说的获取所有字段,而是显式的调用所有字段(对于对性能要求比较高的系统,这个要求并不过分,起码是一个比较好的习惯),下面的用法可以完成预期的作用: Db::table('think_user')->field(true)->select(); field(true)的用法会显式的获取数据表的所有字段列表,哪怕你的数据表有100个字段。

我这么用 Db::table('Config')->field(true)->select();

momoca commented 7 years ago

你想表达什么? @jackboys000

AndyYuenOk commented 7 years ago

@liu21st 我不知道有没有人用sqlite做开发,是sqlite不是mysql,问题反馈,不知道你们有没有试过。 mysql 的语句会带反引号,sqlite生成的语句不会带反引号 另外,上面这个方法

$data = Request::instance()->post();
$data['`group`']=$data['group'];
unset($data['group']);

这样根本不行 database.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

return [
    // 数据库类型
    'type'           => 'sqlite',
    // 服务器地址
    'hostname'       => '',
    // 数据库名
    'database'       => ROOT_PATH . 'application' . DS . '#%73d8898c319532a4.db',
    // 用户名
    'username'       => '',
    // 密码
    'password'       => '',
    // 端口
    'hostport'       => '',
    // 连接dsn
    'dsn'            => '',
    // 数据库连接参数
    'params'         => [],
    // 数据库编码默认采用utf8
    'charset'        => 'utf8',
    // 数据库表前缀
    'prefix'         => '',
    // 数据库调试模式
    'debug'          => true,
    // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'deploy'         => 0,
    // 数据库读写是否分离 主从式有效
    'rw_separate'    => false,
    // 读写分离后 主服务器数量
    'master_num'     => 1,
    // 指定从服务器序号
    'slave_no'       => '',
    // 是否严格检查字段是否存在
    'fields_strict'  => false,
    // 数据集返回类型 array 数组 collection Collection对象
    'resultset_type' => 'array',
    // 是否自动写入时间戳字段
    'auto_timestamp' => true,
    // 是否需要进行SQL性能分析
    'sql_explain'    => false,
];

tp版本,就是现在github上的 用法:sql语句字段没有反引号,反正我的电脑,公司电脑一个样不行 sqlite3,sqlite3,sqlite3

momoca commented 7 years ago

而应该自己去找到问题,我帮你在网上搜索了一下.http://blog.csdn.net/onemetre/article/details/38395625 还有官方的解释:http://www.sqlite.org/lang_keywords.html

AndyYuenOk commented 7 years ago

ok, thanks momoca, 我知道sql关键字的注意的地方。

AndyYuenOk commented 7 years ago

我能问个问题吗? @liu21st mysql数据库驱动

/**
     * 字段和表名处理
     * @access protected
     * @param string $key
     * @param array  $options
     * @return string
     */
    protected function parseKey($key, $options = [])
    {
        $key = trim($key);
        if (strpos($key, '$.') && false === strpos($key, '(')) {
            // JSON字段支持
            list($field, $name) = explode('$.', $key);
            $key                = 'json_extract(' . $field . ', \'$.' . $name . '\')';
        } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) {
            list($table, $key) = explode('.', $key, 2);
            if (isset($options['alias'][$table])) {
                $table = $options['alias'][$table];
            }
        }
        if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
            $key = '`' . $key . '`';
        }
        if (isset($table)) {
            $key = '`' . $table . '`.' . $key;
        }
        return $key;
    }

Sqlite数据库驱动

/**
     * 字段和表名处理
     * @access protected
     * @param string $key
     * @param array  $options
     * @return string
     */
    protected function parseKey($key, $options = [])
    {
        $key = trim($key);
        if (strpos($key, '.')) {
            list($table, $key) = explode('.', $key, 2);
            if (isset($options['alias'][$table])) {
                $table = $options['alias'][$table];
            }
        }
        if (isset($table)) {
            $key = $table . '.' . $key;
        }
        return $key;
    }

为什么sqlite没有过滤?

 if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) {
            $key = '`' . $key . '`';
        }
        if (isset($table)) {
            $key = '`' . $table . '`.' . $key;
        }
hxf0663 commented 7 years ago

composer加载个medoo数据库框架