2011-09-12 20 views
1

講義(「講義テーブル」の行)が削除されると、そのテーブルは「lectures_deleted」テーブルに移動されます。これは一種のバックアップとして機能します。この場合、両方のテーブルから呼び出すことができる必要がありますので、私は 'lectures'テーブルからデータを取得したいと思いますが、ここに存在しない場合は、代わりに'lectures_deleted'テーブル。テーブルにテーブルが存在する場合の選択

以下のコードは、現在このウェブサイトを壊しています。どんな助けでも大歓迎です!

function getModuleCode($id){ 
     $result = mysql_query(' 
      IF EXISTS 
       (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
      ELSE 
       SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"; 
      ') 
     or die(mysql_error()); 
     $row = mysql_fetch_array($result); 
     return $row['module_code']; 
    } 
+0

2つの結果セットは、組合互換性がありますか? (同じ数の列と一致するデータ型) –

答えて

2

方法について:それはまだ講義のテーブルに存在している場合は、この方法もlectures_deletedから選択しますが、あなたの説明によると、私はこれが起こるべきではないと信じて

$result = mysql_query(' 
      (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
     UNION 
      (SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"); 
     ') 

また、講義テーブルで「削除済み」フラグ(1ビットフィールド)を使用して、講義が削除されたかどうかを示すことをお勧めします。このようにして、削除されたエントリを別のテーブルに移動する必要はありません。

+0

ありがとう、これは完全に機能しました! 私は削除された講義のために別のテーブルを持っている理由は、一種の回復オプションと呼ばれ、ソフトウェアをより速く実行できるようにするために、照会されたときにメインテーブルのサイズを最小限にしたかったからです。 – Ollie

+0

@Ollie tableAからtableBへのデータの移動では、常にtableAとtableBの両方から選択するとクエリが高速に実行されません。 –

+0

@Andreasウェブサイト上の特別なバックアップページの両方のテーブルから選択されていますが、頻繁にアクセスされることはありません。 – Ollie

1
SELECT 1 AS pref, * FROM lectures WHERE lecture_id="'.$id.'" 
UNION 
SELECT 2 AS pref, * FROM lectures_deleted WHERE lecture_id="'.$id."' 
ORDER BY pref 
LIMIT 0,1 
-1

あなたの質問に正確な答えはありませんが、あなたのlecturesテーブルの値が0または1のis_deletedという列を持つようにデータモデルを変更しないのはなぜですか?そうすれば、削除された講義を別のテーブルに保存する必要はありません。削除されたまたは削除されていない講義をフェッチする(または両方をフェッチするWHERE句を省略する)クエリには、WHERE is_deleted = 0またはWHERE is_deleted = 1のようなWHERE句を含めるだけで済みます。

現在のデータモデルで解決したい場合は、2つのクエリで実行します。私はmysql_queryが現在のSQL文をサポートするとは思わない。したがって、最初にlecturesテーブルをクエリし、ゼロの結果が得られた場合は、その存在がlectures_deletedであることを確認してください。

また、あなたの$id変数が正確にどこから来るのか分かりませんが、クエリがSQL injectionsに対して脆弱でないことを確認したい場合があります。

+0

私は両方のアプローチに取り組んできましたが、私はあなたのことがはるかに劣っていると感じました。必要に応じて、削除された行を結合するIMOの方がはるかに優れています。通常の場合には 'is_deleted = 0'をフィルタリングする必要があります。 – onedaywhen

+0

@onedaywhen:どのような意味で優れていますか?もっと早く?書きやすい?簡単にデバッグできますか? – Sorpigal

+0

コーダーSQL DMLコーダーの痛みが軽減されます。 'COALESCE(is_deleted、 'F')= 'F''をテストする必要はありません。例えば、SQL DDLコーダの苦痛を軽減する。一意の制約に「UNIQUE」を単に使用することはできません。なぜなら、値は「削除された」エンティティに対して合法的に複製されるからです。パフォーマンスの改善など'is_deleted'フラグを付けてテーブルに戻ってくる必要はありません。 – onedaywhen

0

講義がlecturesに存在する場合は、何も返さないので、あなたの現在のクエリが間違っているので、あなたはこのようにそれを変更する必要があります。

IF EXISTS (SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
    SELECT * FROM lectures WHERE lecture_id="'.$id.'" 
ELSE 
    SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'"; 

しかし、性能面、それはUnionを使用することをお勧めします演算子は、それは一つだけが(両方のテーブルのすべての列が同じで、同じ順序であると仮定して)選択を行いますので、あなたのケースで:

select * from lectures where lecture_id=$id 
union 
select * from lectures_deleted where lecture_id=$id 
0

IF ... ELSE決定文はで使用することはできません直接のMySQLクエリ。ファンクション/ストアドプロシージャでのみ使用できます。
あなたは試すことができ、この

$result = mysql_query(SELECT * FROM lectures WHERE lecture_id="'.$id.'") 
if (mysql_num_rows($result) == 0) 
    $result = mysql_query(SELECT * FROM lectures_deleted WHERE lecture_id="'.$id.'") 
関連する問題