如何在使用PDO时设置SQL模式?


How can I set the SQL mode while using PDO?

我试图设置SQL模式,我不知道如何使用PDO。我正在尝试在MySQL中设置传统模式,不允许无效日期。

有人能帮忙吗?

这只适用于您的连接。该命令将在PDO连接后立即运行:

$pdo = new PDO(
     $dsn, 
     $username, 
     $password, 
     array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode="TRADITIONAL"') 
);

参见PHP: MySQL (PDO)
看到5.1.6。Server SQL Modes

在运行时设置sql_mode时,可以使用可选的'SESSION'变量。这样就不会影响到其他客户。您可以设置SESSION sql_mode,然后在查询完成后将其设置回之前的值。通过这种方式,可以为特定的操作设置sql_mode。

从MySql手册:

"你可以在运行时使用SET来改变SQL模式[GLOBAL|SESSION] sql_mode='modes'语句设置sql_mode系统价值。设置GLOBAL变量需要SUPER权限和影响从那时起连接的所有客户端的操作。设置SESSION变量只影响当前客户端。任何客户端可以随时修改自己的会话sql_mode值。"

我个人在数据库类中添加了一些方法来处理这个问题。initSqlMode()将执行查询SELECT SESSION。Sql_mode’,并将默认值存储为类变量。setSqlMode()将允许您将SESSION sql_mode设置为(已验证的)自定义值。resetSqlMode()将SESSION sql_mode设置回默认值。在任何时候操作sql_mode时,我都使用SESSION变量。

那么您可以执行如下操作。注意,这只是伪代码;在我的例子中没有任何东西可以防止SQL注入或参数化SQL查询。

$db = new database();
$badqueryresult = $db->executeStrict('BAD SQL QUERY');
Class database {
     ...
     function executeStrict($query){
      $this->initSqlMode();
      $this->setSqlMode('STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION');
      $result = $this->Execute($query);
      $this->resetSqlMode();
      return $result;
     }
}
function get_pdo($c =false){
    if (!$c){$c=get_config();}
    $pdo=new PDO($c['dsn'] , $c['db_user'], $c['db_password']);
    $better_sql_defaults=array (
        'SET SESSION sql_warnings=1',
        'SET NAMES utf8',
        'SET SESSION sql_mode = "ANSI,TRADITIONAL" ',
    );
    // throw an exception on errors
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    foreach ($better_sql_defaults as $sql){
        $pdo->query($sql);
    }
    return $pdo;
}

使用此命令清除sql_mode变量:

$db_conn->query("SET SESSION sql_mode=''")->execute();

或者这个来删除一个特定的项:

$db_conn->query("SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'WRITE_HERE_THE_NAME',''));")->execute();

如果你想全局修改,你需要有一些管理员权限。

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'WRITE_HERE_THE_NAME',''));