2012-03-19 29 views
13

SQLiteはデフォルトで外部キーを強制しません。私はsqlitejdbc-v056.jarを使用していますが、PRAGMA foreign_keys = ON;を使用すると外部キー制約が有効になり、接続ごとに有効にする必要があることがわかりました。JavaからSQLiteに外部キー制約を適用するにはどうすればよいですか?

私の質問は:このコマンドを有効にするには、どのJava文を実行する必要がありますか?私が試した:

connection.createStatement().execute("PRAGMA foreign_keys = ON"); 

Properties properties = new Properties(); 
properties.setProperty("PRAGMA foreign_keys", "ON"); 
connection = DriverManager.getConnection("jdbc:sqlite:test.db", properties); 

connection = DriverManager.getConnection("jdbc:sqlite:test.db;foreign keys=true;"); 

が、これらの作品のどれを。私がここに欠けているものはありますか?

私はthis answerを見てきましたが、私はまったく同じことをしたい、JDBCのみを使用します。

+1

使用しているSQLiteのバージョンは? (外来キーの制約は3.6.19で導入されました) – dan04

+0

3.6.14.2、明らかに。気づかなかった – Zarjio

答えて

14

あなたはSQLite Foreign Key Support pageを見てみると、私は

  1. SQLliteあなたはまだあなたがする必要があるPRAGMA
  2. との各接続のためにそれをオンにする必要があり、外部キーのサポート
  3. してコンパイルされなければならないことを解釈しますあなたがテーブルにhereより引用

広告1)を作成する際の制約として、外部キーを定義します。

If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined).

PRAGMA foreign_keys;の結果は何ですか?

更新:ご意見から私はあなたが3.6.14.2を使用していることを確認しています。これはあなたのバージョンが外部キー制約をサポートしていないことを意味します。これが可能なら、SQLiteを更新する必要があります!

広告2)最初のコードスニペットはPRAGMAをステートメントとして実行しますが、これはうまくいかないと思います。 3番目のスナップは、あなたのコメントに基づいて動作しませんでした:SQLiteドライバは、接続設定として "foreign keys = true"部分を取るのではなく、文字列全体をデータベースの場所として解釈します "。 。?仕事

広告3)あなたがhereより引用外部キーをサポートして表を作成しました:

CREATE TABLE artist(
    artistid INTEGER PRIMARY KEY, 
    artistname TEXT 
); 
CREATE TABLE track(
    trackid  INTEGER, 
    trackname TEXT, 
    trackartist INTEGER, 
    FOREIGN KEY(trackartist) REFERENCES artist(artistid) 
); 
+0

はい、テーブルは外部キーをサポートして作成されました。そして、私はすぐに3番目の方法がまったく動作しないことに注意してください。SQLiteドライバは、接続設定として "foreign keys = true"部分を取る代わりに、データベース全体の文字列をデータベースの位置として解釈します。 – Zarjio

1

リンクした質問に基づいて

connection = DriverManager.getConnection("jdbc:sqlite:test.db;foreign keys=true;"); 

を試してみて、それが有力候補になりそうです。

+0

申し訳ありませんが、私はすでにそれを試みたと述べているはずでしたし、どちらもうまくいきませんでした。 – Zarjio

0

同じ問題をグーグルでいる間、私はこの質問を見つけた私が使用していますZentusからsqlitejdbc-v056.jarを、使用していました。古いバージョンのSQLiteドライバであり、外部キーをサポートしていません。

私はそう、私はこれらのドライバの違いを研究していないが、両者の間のホットスイッチが何かを壊し、私の問題を修正しなかったMaven Repository

からXerialドライバv3.7.2のようです何しようとしましたこれが誰かを助けることを願っています。私が試したLinuxデスクトップ、オン

1

connection = DriverManager.getConnection("jdbc:sqlite:/path/to/test.db;foreign keys=true;"); 

sqlite3の(3.7.13)は、私のデータベースファイル/path/to/test.db;foreignキー=真だと思いました。これは奇妙につながったが、私は適切な、エラーを推測:表が、私はそうのようなプロパティに外部キーステートメントを詰めることで、私は、これらの問題の両方を固定していたと思っhow to solve no such table while inserting exception in sqlite data base

を参照してください

存在しません:

private final Properties connectionProperties = new Properties(); 
connectionProperties.setProperty("PRAGMA foreign_keys", "ON"); 
private final String connectionString = String.format("jdbc:sqlite:%s", absolute_path_to_sqlite_db); 
Connection connection = DriverManager.getConnection(connectionString, connectionProperties); 

でも、データベース名の問題が解決されても、SQLiteは引き続き制約違反を許可していました。いくつかのよりXerialのドライバとヌードリング、これは最終的にどのような仕事をされています。このような

private final Properties connectionProperties = new Properties(); 
SQLiteConfig config = new SQLiteConfig(); 
config.enforceForeignKeys(true); 
connectionProperties = config.toProperties(); 
private final String connectionString = String.format("jdbc:sqlite:%s", absolute_path_to_sqlite_db); 
Connection connection = DriverManager.getConnection(connectionString, connectionProperties); 
26

コード:

DriverManager.getConnection("jdbc:sqlite:some.db;foreign keys=true;") 

は動作しません。 org.sqlite.SQLiteConfigを作成し、DriverManagerからgetConnectionを呼び出すときにプロパティとして設定する必要があります。

public static final String DB_URL = "jdbc:sqlite:database.db"; 
public static final String DRIVER = "org.sqlite.JDBC"; 

public static Connection getConnection() throws ClassNotFoundException { 
    Class.forName(DRIVER); 
    Connection connection = null; 
    try { 
     SQLiteConfig config = new SQLiteConfig(); 
     config.enforceForeignKeys(true); 
     connection = DriverManager.getConnection(DB_URL,config.toProperties()); 
    } catch (SQLException ex) {} 
    return connection; 
} 

このコードはthisから取得しました。

+0

これは魅力のように機能します!答えとして受け入れられるはずの答えの1つです。 –

+0

ありがとう!素晴らしい答え。 – noobProgrammer

+0

パーフェクト、それは私の問題を解決しました。 –

4

私は残念ながら、以前のポスターの答えではなく、ここで来るかもしれない誰、最初のコードスニペット用ヘッドアップとしてコメントすることはできません。

connection.createStatement().execute("PRAGMA foreign_keys = ON"); 

のSQLiteのバージョンがあるときに絶対に動作しません外部キーサポートをサポートしています。

0

このページはClojureに翻訳する際に役立ちましたが、私の解決策は異なりました。だから、後世のために、OPは、Javaを求めたにもかかわらず、これは私はClojureの中でそれをやった方法です:

(def db-spec {:connection-uri "jdbc:sqlite:db.sqlite3?foreign_keys=on;"})

0

私はMyBatisの-config.xmlに、MyBatisのを使用します。
<property name="url" value="jdbc:sqlite:example.db?foreign_keys=on;"/>
ための作業だというmybatisフレームワーク。

関連する問題