0

sqlite3 への接続に PDO を使用していますが、何らかの理由で外部キーを機能させることができません。ドキュメントによると、この「PRAGMA short_column_names=1」はそれを有効にする必要があります。私はこれをします:

$con = new PDO('sqlite:z:/testing.db');
$res = $con->exec('PRAGMA foreign_keys=ON');
var_dump($res);die();

これは 0 を返します。外部キーを使用して実際のテーブルを作成しようとしましたが、うまくいきませんでした。ただし、SQLite3 クラスへの直接リクエストは機能しました。

$con = new SQLite3('z:/testing.db');
$con->exec('PRAGMA foreign_keys = ON;');
var_dump($con->query('PRAGMA foreign_keys;')->fetchArray());

これは array(2) { [0]=> int(1) ["foreign_keys"]=> int(1) } を返します。

SQLite3::version() によると、私は sqlite バージョン 3.7.7.1 を持っています。私の PHP バージョンは 5.3.18 で、Windows で実行されています。

PDOで実行するのを手伝ってください。ありがとう!

4

1 に答える 1

7

PRAGMA short_column_names=1;外部キー制約がSQLiteで機能するために、PDOで発行する必要があるという考えを私は知りません。ただし、PDOについても問題を解決する必要があります。PRAGMA foreign_keys = ON;

これを試してみてください:

<?php

// SQL for creating database structure
$databaseSql = <<<SQL
    CREATE TABLE `user` (
        `id` INTEGER PRIMARY KEY AUTOINCREMENT,
        `name` TEXT NOT NULL,
        UNIQUE( `name` )
    );

    CREATE TABLE `userProfile` (
        `userId` INTEGER NOT NULL CONSTRAINT `userProfile_userId` REFERENCES `user`( `id` ) ON UPDATE CASCADE ON DELETE CASCADE,
        `image` TEXT NOT NULL
    );
SQL;

// SQL for inserting dummy data
$dataSql = <<<SQL
    INSERT INTO `user` VALUES( 1, "John" );
    INSERT INTO `user` VALUES( 2, "Mary" );
    INSERT INTO `user` VALUES( 3, "Joe" );
    INSERT INTO `userProfile` VALUES( 1, "/images/john.jpg" );
    INSERT INTO `userProfile` VALUES( 2, "/images/mary.jpg" );
    INSERT INTO `userProfile` VALUES( 3, "/images/joe.jpg" );
SQL;

// create a temporary SQLite instance in memory
$db = new PDO( 'sqlite::memory:', null, null, array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false
) );

// activate use of foreign key constraints
$db->exec( 'PRAGMA foreign_keys = ON;' );

// create database
$db->exec( $databaseSql );
// insert dummy data
$db->exec( $dataSql );

// should dump 3 records
var_dump( $db->query( 'SELECT * FROM `userProfile`;' )->fetchAll() );

// delete 1 user, cascade deleting 1 userProfile as well
$db->exec( 'DELETE FROM `user` WHERE `id` = 1;' );

// should dump 2 records
var_dump( $db->query( 'SELECT * FROM `userProfile`;' )->fetchAll() );

結果は次のようになります。

array(3) {
  [0]=>
  array(2) {
    ["userId"]=>
    string(1) "1"
    ["image"]=>
    string(16) "/images/john.jpg"
  }
  [1]=>
  array(2) {
    ["userId"]=>
    string(1) "2"
    ["image"]=>
    string(16) "/images/mary.jpg"
  }
  [2]=>
  array(2) {
    ["userId"]=>
    string(1) "3"
    ["image"]=>
    string(15) "/images/joe.jpg"
  }
}
array(2) {
  [0]=>
  array(2) {
    ["userId"]=>
    string(1) "2"
    ["image"]=>
    string(16) "/images/mary.jpg"
  }
  [1]=>
  array(2) {
    ["userId"]=>
    string(1) "3"
    ["image"]=>
    string(15) "/images/joe.jpg"
  }
}
于 2012-11-23T18:22:22.423 に答える