SQLite将NULL值添加到NOT NULL列中

时间:2013-04-21 00:13:41

标签: php sqlite null

我正在创建一个包含NOT NULL列的表:

CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY, Username TEXT UNIQUE NOT NULL, Password TEXT NOT NULL);

但SQLite很乐意为这些列添加NULL值:

<?php

error_reporting(E_ALL);
date_default_timezone_set('Europe/Helsinki');
ini_set('default_charset', 'UTF-8');
mb_internal_encoding("UTF-8");
header('Content-Type: text/html; charset=UTF-8');

// ---

const DB_FILE = "auth.db";
//$username = "john";
//$password = "secret";
$username = '';
$password = '';

// ---

// open db
//$db = new PDO('sqlite:'.DB_FILE);
$db = new PDO('sqlite::memory:');

// set attributes
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

// create the table
$db->exec("CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY, Username TEXT UNIQUE NOT NULL, Password TEXT NOT NULL);");

$statement = "INSERT INTO Users (Username, Password) VALUES (:Username,:Password);";    
$query = $db->prepare($statement);
$query->bindValue(':Username', $username, SQLITE3_TEXT);
$query->bindValue(':Password', $password, SQLITE3_TEXT);
$ok = $query->execute();

$result = $db->query('SELECT * FROM Users');
if (!$result) die ("oops!"); // will not produce anything when errormode is on

echo "<pre>\n";

foreach($result as $row)
{
    echo "Id: " . $row['Id'] . "\n";
    echo "Username: " . $row['Username'] . "\n";
    echo "Password: " . $row['Password'] . "\n";
}

$db = NULL;

?>

SQLite不应该允许这样做。我做错了什么?

更新于2013-04-23~00:35 Z

以下是对Diamond Geezer答案的评论。

SQLite停止执行这些语句:

$db->exec("INSERT INTO Users (Username, Password) VALUES ('','');");
$db->exec("INSERT INTO Users (Username, Password) VALUES ('a','aa');");
$db->exec("SELECT * FROM Users;");

但不是这些:

$username = '';
$password = '';
$statement = "INSERT INTO Users (Username, Password) VALUES (:Username,:Password);";    
$query = $db->prepare($statement);
$query->bindValue(':Username', $username, SQLITE3_TEXT);
$query->bindValue(':Password', $password, SQLITE3_TEXT);
$ok = $query->execute();

我认为这必须与准备声明有关。

1 个答案:

答案 0 :(得分:2)

用户名和密码不为NULL;它们是零长度字符串:

$username = '';
$password = '';

这就是他们插入的原因。

在回复您的评论时,您可以使用CHECK约束来停止插入零长度字符串,如下所示。

CREATE TABLE IF NOT EXISTS Users 
(
  Id INTEGER PRIMARY KEY, 
  Username TEXT UNIQUE NOT NULL CHECK(Username<>''), 
  Password TEXT NOT NULL CHECK(Password<>'')
);

这是SQL Fiddle。语句:INSERT INTO Users (Username, Password) VALUES ('','');因错误而失败:由于约束失败而无法执行语句(19约束失败),而语句:INSERT INTO Users (Username, Password) VALUES ('a','aa');成功。