如何根据传递的参数 incr/decr 列值?
How to incr/decr column values based on passed parameters?
希望为单个测试创建动态存储过程-table 我可以根据传递给它的参数更改其中一列中的值。
示例:我有一个 table,我希望能够将电影 (MovieID
) 从一家商店 (StoreID
) “移动”到另一家商店 (StoreID
),并展示该移动有货 (Movies_in_stock
)。一旦存储过程具有 运行(并且取决于输入的参数),它应该显示例如在 StoreID 1
中带有 MovieID = 100
的 1 部电影已移至 StoreID 2
- Movies_in_stock
随后在 StoreID = 1
中减少并在 [= 中增加(加上新行) 23=].
请参阅下面的 table 更改。
| StoreID | MovieID | Movies_in_stock |
| 1 | 100 | 10 |
| 2 | 200 | 20 |
| 3 | 300 | 50 |
| 1 | 400 | 100 |
| 2 | 500 | 5 |
在 运行 存储过程之后,我期望这个数据:
| StoreID | MovieID | Movies_in_stock |
| 1 | 100 | 9 |
| 2 | 200 | 20 |
| 3 | 300 | 50 |
| 1 | 400 | 100 |
| 2 | 500 | 5 |
| 2 | 100 | 1 |
到目前为止我做了什么:
- 设置参数:
MovieID = @MovieID, StoreID = @StoreID_From , StoreID = @StoreID_To, Movies_in_stock = @Stock (optional param)
- 试图弄清楚如何将
CASE
与 UPDATE
结合起来:
UPDATE Table1
SET Movies_in_stock =
(CASE WHEN @StoreID = x AND @StoreID = y
THEN (Movies_in_stock = Movies_in_stock +/- @Movies_in_stock)
ELSE 0
END)
WHERE @MovieID = z
打开并感谢收到的任何suggestions/help/ideas/improvements。
您实际上在这里尝试做的是合并。
- 构建虚拟源 table 更改:From 商店获得负数量。
- 将其合并到现有 table 中,在没有该位置和电影组合的行的情况下插入
CREATE OR ALTER PROCEDURE MoveStock
@MovieID int,
@StoreID_From int,
@StoreID_To int,
@StockToMove int = 1;
AS
WITH Source AS (
SELECT StoreID = @StoreID_To, DiffQty = @StockToMove
UNION ALL
SELECT @StoreID_From, (-@StockToMove)
),
Target AS (
SELECT *
FROM Table1
WHERE MovieID = @MovieID
AND StoreID IN (@StoreID_From, @StoreID_To) -- this line for performance only, try without
)
MERGE Target t
USING Source s
ON s.StoreID = t.StoreID
WHEN MATCHED AND t.Movies_in_stock + s.DiffQty <= 0
THEN DELETE -- decide whether you want this condition
WHEN MATCHED THEN
UPDATE SET Movies_in_stock += s.DiffQty
WHEN NOT MATCHED THEN
INSERT (StoreID, MovieID, Movies_in_stock)
VALUES (S.StoreID, @MovieID, s.DifQty)
;
希望为单个测试创建动态存储过程-table 我可以根据传递给它的参数更改其中一列中的值。
示例:我有一个 table,我希望能够将电影 (MovieID
) 从一家商店 (StoreID
) “移动”到另一家商店 (StoreID
),并展示该移动有货 (Movies_in_stock
)。一旦存储过程具有 运行(并且取决于输入的参数),它应该显示例如在 StoreID 1
中带有 MovieID = 100
的 1 部电影已移至 StoreID 2
- Movies_in_stock
随后在 StoreID = 1
中减少并在 [= 中增加(加上新行) 23=].
请参阅下面的 table 更改。
| StoreID | MovieID | Movies_in_stock |
| 1 | 100 | 10 |
| 2 | 200 | 20 |
| 3 | 300 | 50 |
| 1 | 400 | 100 |
| 2 | 500 | 5 |
在 运行 存储过程之后,我期望这个数据:
| StoreID | MovieID | Movies_in_stock |
| 1 | 100 | 9 |
| 2 | 200 | 20 |
| 3 | 300 | 50 |
| 1 | 400 | 100 |
| 2 | 500 | 5 |
| 2 | 100 | 1 |
到目前为止我做了什么:
- 设置参数:
MovieID = @MovieID, StoreID = @StoreID_From , StoreID = @StoreID_To, Movies_in_stock = @Stock (optional param)
- 试图弄清楚如何将
CASE
与UPDATE
结合起来:
UPDATE Table1
SET Movies_in_stock =
(CASE WHEN @StoreID = x AND @StoreID = y
THEN (Movies_in_stock = Movies_in_stock +/- @Movies_in_stock)
ELSE 0
END)
WHERE @MovieID = z
打开并感谢收到的任何suggestions/help/ideas/improvements。
您实际上在这里尝试做的是合并。
- 构建虚拟源 table 更改:From 商店获得负数量。
- 将其合并到现有 table 中,在没有该位置和电影组合的行的情况下插入
CREATE OR ALTER PROCEDURE MoveStock
@MovieID int,
@StoreID_From int,
@StoreID_To int,
@StockToMove int = 1;
AS
WITH Source AS (
SELECT StoreID = @StoreID_To, DiffQty = @StockToMove
UNION ALL
SELECT @StoreID_From, (-@StockToMove)
),
Target AS (
SELECT *
FROM Table1
WHERE MovieID = @MovieID
AND StoreID IN (@StoreID_From, @StoreID_To) -- this line for performance only, try without
)
MERGE Target t
USING Source s
ON s.StoreID = t.StoreID
WHEN MATCHED AND t.Movies_in_stock + s.DiffQty <= 0
THEN DELETE -- decide whether you want this condition
WHEN MATCHED THEN
UPDATE SET Movies_in_stock += s.DiffQty
WHEN NOT MATCHED THEN
INSERT (StoreID, MovieID, Movies_in_stock)
VALUES (S.StoreID, @MovieID, s.DifQty)
;