カスタムストアドプロシージャの作成を任されました:
exec UPDATE_PROJECT_ORDER @PROJECTID=12, @UPDATEMODE=0
これは、テーブルの行が更新された後に実行されます。
残念ながら、それは私を本当に困惑させました(それが可能かどうかさえわからないという点まで)私は自分がしていることを単純化しようとしており、コード自体だけでボードに支援を求めることができるかどうか疑問に思っていました...
そのため、ストアド プロシージャ/コードの目的は、アイテムのリストを一般的に順番に並べ替えることです。並べ替えは、渡されたパラメーターに基づいて変更されます。ユーザーとその周りのリストの残りを並べ替えるか、シーケンスの次の番号として番号を付け直します。ほとんどの場合、UPDATEMODE=0 がデフォルトになると想定できると思います。
次のようなテーブルがあります。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 1 | |
| 11 | 2 | |
| 12 | 3 | |
| 13 | 4 | |
---------------------------------------
ユーザーが ID 12 (ID はストアド プロシージャで渡されます) のレコードに高い優先度 (たとえば 1) を与えることにした場合、他のレコード (10 / 11 / 13) を順番に再設定する必要があります。フロントエンドでの表示方法に影響します (2 / 3 / 4)。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 2 | 1 |
| 11 | 3 | 2 |
| 12 | 1 | 3 |
| 13 | 4 | 4 |
---------------------------------------
これの別の例は、レコード ID 12 の位置が 1 から 7 に変更されるため、このデータ セットは次のようになります。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 2 | 1 |
| 11 | 3 | 2 |
| 12 | 1/7 | 3 |
| 13 | 4 | 4 |
---------------------------------------
位置データは次のように並べ替えられます。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 1 | 2 |
| 11 | 2 | 3 |
| 12 | 7 | 1 |
| 13 | 3 | 4 |
---------------------------------------
前述のように、ストアド プロシージャでは、関数の動作を変更する別のパラメータ (0 または 1 の @UPDATEMODE) を渡す必要があります。これにより、ユーザーは必要な位置を指定して順序を変更できます。たとえば、行 3 の優先順位を値 1 から値 7 に更新します。
このデータ セットの行 12 の位置の値は 1 ですが、UPDATEMODE を 1 に指定して 7 に変更されています。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 2 | 1 |
| 11 | 3 | 2 |
| 12 | 1/7 | 3 |
| 13 | 4 | 4 |
---------------------------------------
次のようにリストを並べ替えます。
---------------------------------------
| ID | POSITION | OLD_POS |
---------------------------------------
| 10 | 1 | 2 |
| 11 | 2 | 3 |
| 12 | 4 | 1 |
| 13 | 3 | 4 |
---------------------------------------
この例では、ストアド プロシージャは次のように呼び出されます。
exec UPDATE_PROJECT_ORDER @PROJECTID=12, @UPDATEMODE=1
これは私が取り組んできたSQLコードです:
-- Declare variables
DECLARE @PROJECTID INTEGER
DECLARE @CURRENTPOSITION INTEGER
DECLARE @ROLLBACKPOSITION INTEGER
DECLARE @STARTPOSITION INTEGER
DECLARE @ENDPOSITION INTEGER
-- For testing hardcode a REQUEST ID
SET @PROJECTID = 12
-- Start Position value
SET @STARTPOSITION = 1
-- End Position value
SELECT @ENDPOSITION = COUNT(ID) FROM PROJECT WHERE PROJECT_ORDER IS NOT NULL
-- Update Rollback column with current value
UPDATE PROJECT SET OLD_POS = POSITION WHERE POSITION IS NOT NULL
DECLARE cursorProjectPositionUpdate CURSOR fast_forward
FOR
SELECT ID, POSITION, OLD_POS
FROM PROJECT
WHERE ID = @PROJECTID
AND POSITION IS NOT NULL
OPEN cursorProjectPositionUpdate
FETCH NEXT FROM cursorProjectPositionUpdate INTO @PROJECTID, @CURRENTPOSITION, @ROLLBACKPOSITION
WHILE @@FETCH_STATUS = 0
BEGIN
WHILE (@STARTPOSITION <= @ENDPOSITION)
IF @STARTPOSITION = 1
UPDATE PROJECT
SET POSITION = @STARTPOSITION
WHERE ID = @PROJECTID
AND OLD_POSITION = @ROLLBACKPOSITION
ELSE
UPDATE PROJECT
SET POSITION = @STARTPOSITION
WHERE OLD_POS = @ROLLBACKPOSITION
AND ID <> @PROJECTID
SET @STARTPOSITION = @STARTPOSITION + 1
FETCH NEXT FROM cursorProjectPositionUpdate INTO @PROJECTID, @CURRENTPOSITION, @ROLLBACKPOSITION
END
CLOSE cursorProjectPositionUpdate
DEALLOCATE cursorProjectPositionUpdate
再注文できる最大レコード数は 25 という厳しい制限があるため、カーソルを使用したので、パフォーマンスについて過度に心配する必要はありません。テーブルには 25 を超えるレコードがある可能性がありますが、AND POSITION IS NOT NULL 句を使用してレコードを除外しようとしたのはそのためです。これが受け入れられることを願っています。
私の頭の中の考えは、位置を持つレコードの合計数を数え、最初のレコードを位置 1 に設定し、その後残りを次の順序に設定することをループすることです。
私が見つけた最大の問題は、レコードの一致、つまり WHERE 句にあります。ストアド プロシージャによって渡される唯一のものは、位置 1 に設定したい ID であるため、どのレコードが次に来るかをどのように知ることができますか? ...ロジックは、リストを下っていく次に小さいID番号でなければならないということです。
これは、MS SQL Server で行われています。
一時テーブルの作成を避けようとしているので、これをすべて 1 つにできるかどうかを確認する必要があります。
これが誰かにとって何らかの意味をなすことを願っています.私は解決策を受け入れており、できるだけ多くの情報を共有します.
どうもありがとう!
追加
以下の回答に基づいて、これについてもう少し考えてきました。これも、最初からできるだけ単純にしようとしているので、PROJECT ID値を渡したストアドプロシージャがあるので、すべてをループするとどうなりますか?私のプロジェクトIDと一致しない値のうち、2から始まり、私が持っているレコードの数に基づいたエンドポイントまでそれらをリセットし、それらが順番にあると、渡されたプロジェクトの位置を1に設定します. これが更新モードのオプションに対応していないことはわかっていますが、複雑さが増しているのではないかと心配しています。
コードに関する限り、次のようなことについてどう思いますか。
-- Declare variables
DECLARE @PROJECTID INTEGER
DECLARE @STARTPOSITION INTEGER
DECLARE @ENDPOSITION INTEGER
-- Hardcoded for testing
SET @PROJECTID = 25061
-- Start Position value
SET @STARTPOSITION = 2
-- End Position value
SELECT @ENDPOSITION = COUNT(ID) FROM PROJECT WHERE PROJECT_ORDER IS NOT NULL AND ID <> @PROJECTID
-- Update Rollback column with current value
UPDATE PROJECT SET PROJECT_ORDER_RB = PROJECT_ORDER WHERE PROJECT_ORDER IS NOT NULL
-- Loop other records
WHILE (@STARTPOSITION <= @ENDPOSITION)
UPDATE PROJECT SET PROJECT_ORDER = @STARTPOSITION WHERE ID <> @PROJECTID
AND PROJECT_ORDER IS NOT NULL AND (PROJECT_ORDER = 1 OR PROJECT_ORDER => @STARTPOSITION OR PROJECT_ORDER <= @ENDPOSITION)
SET @STARTPOSITION = @STARTPOSITION + 1
-- Finally set passed in Project to Position 1
UPDATE PROJECT SET PROJECT_ORDER = 1 WHERE ID = @PROJECTID