1

私はテーブルを持っています:

INSTRUCTIONS:
  RecipeID
  Step
  ...

RecipeID別のシステムによって生成されます。の明示的な外部キー関係は必要ありませんRecipeID。特定のレシピのステップを挿入すると、インクリメントしInstructionsたいと思いStepます。ステップを新しいレシピに追加するときは、次のstepように 0 に戻す必要があります。

RecipeID | Step
---------------
    0    |  0
    0    |  1

RecipeID | Step
---------------
    0    |  0
    0    |  1
    0    |  2

RecipeID | Step
---------------
    0    |  0
    0    |  1
    0    |  2
    1    |  0

この種の動作をどのように生成しますか?

4

2 に答える 2

2

これをしないでください あなた自身の質問は、それが悪い考えであることを示しています。部分的なキーを取得するにはどうすればよいですか? 定義上、部分キーを一意にすることはできません。

ステップから必要なのは順序だけです。それらを 0 から n として表示する (または Row_number でクエリする) のは簡単です。

見逃したステップを挿入したり、それらを交換したりするために、何をしなければならないかを考えてください...

RecipeStepID (代理主キーとして)

インデックスとしての RecipeID,StepNumber

テーブルへのすべての外部キー リンクは代理キーを使用します

次に、再注文は StepNo をいじるだけです

あなたが試みているアプローチが災害にならないのを見たことがありません。ミトンを脱がずに災害として始まらなかった回数を数えることができます。

于 2013-01-23T23:56:26.900 に答える
0

免責事項: 下部の注意事項を参照してください。トリガーを使用することは必ずしもお勧めしません。

instead ofトリガーを使用して、step挿入される値を変更できます。

Create Trigger Instructions_UpdateSet
  On [Instructions]
  Instead of Insert
AS
BEGIN
  insert instructions
  select
    i.recipe,
    coalesce(ii.maxstep, -1)
      + row_number() over (partition by i.recipe order by i.step),
    i.instruction
  from inserted i
  left join (select recipe, max(step) as maxstep from instructions group by recipe)
    ii on i.recipe = ii.recipe
END;

これにより、単一または複数のレコードの挿入がシームレスに処理されます。単一のクエリで複数のレコードを挿入する場合は、step値を指定して挿入された受信レコードの順序を示すことができます。これらのレコードは適切に並べ替えられ、既存のレコードの後に​​続くように番号が付け直されます。

デモ: http://www.sqlfiddle.com/#!6/b13d5/1


アプリケーションでトリガーを使用する際の注意事項:

  • トリガーは非常によく隠れるので、忘れがちです。それらを必ず文書化してください。そうしないと、次の開発者が挿入するデータがデータベース内で同じでないと混乱します。
  • キャッシュ レイヤーを使用している場合は、レコードを挿入した後にキャッシュを更新して、トリガーによって発生した変更を取得してください。
  • 一般に、ビジネス ロジックのトリガーは避けることをお勧めします。パフォーマンスを求める場合は、目的と動作がより明確なストアド プロシージャを使用することをお勧めします。トリガーは、データ検証、カスケード更新/削除、監査などの透過的な操作に最適です。
于 2013-01-24T00:03:46.667 に答える