最近因為出包了所以要撈訂單
但因為邏輯有點複雜覺得組SQL快要我命,所以後來寫程式解決了
但是坐我隔壁的新主管大鈞跟我說可以試試看用 CURSOR 來做
他雖然給了我範例,但我已經用程式寫完了
不過覺得很好奇所以又用他給的範例寫了一遍
但他有提醒我用這東東要非常小心......弄得不好會影響到線上服務
邏輯就是,如果....
==========================================
訂單名細 ORDERD 內的欄位
RBICE <> RBUPC 代表為一般書籍
RBICE = RBUPC 代表為加購品
如果一個訂單內一般書籍的購買量 >= 10 就要打 29折
如果 < 10 就打 39折,加購品都不打折
然後全部名細加起來的總額要等於訂單主檔ORDERM 的總金額 RAAMT
然後如果訂單名細總額 <> 訂單主檔的 RAAMT 欄位,就要撈出來
==========================================
以下是完成品
(table + field name 已經改掉,所以沒有洩密)
SET NOCOUNT ON
DECLARE @NO VARCHAR(10)
-- 這邊用個 temp table 放結果
DECLARE @TEMP TABLE (
ORDNO VARCHAR(10),
AMT INT,
RAAMT INT
)
-- DECLARE 游標名稱 CURSOR FOR 你的SQL
DECLARE MYCURSOR CURSOR FOR
SELECT ORDNO FROM ORDERM A JOIN ORDERD B ON A.ORDNO = B.ORDNO_D
WHERE RASTA NOT IN (4,7) AND ORDNO LIKE '3%' AND CDATE BETWEEN '2012/10/1' AND '2012/12/31'
GROUP BY ORDNO
-- 開啟游標
OPEN MYCURSOR
-- 抓取資料並寫到 @NO
FETCH NEXT FROM MYCURSOR INTO @NO
-- 如果@@FETCH_STATUS = 0 就跑迴圈
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @CON INT
-- 下面就是我過濾的邏輯了,如果 RBICE = RBUPC 就是 G,反之則是 S
-- 然後取 S 的值,大於等於10表示該訂單要29折,反之39折
SELECT @CON = ISNULL(COUNT(*),0) FROM (
SELECT CASE WHEN RBICE = RBUPC THEN 'G' ELSE 'S' END AS PTYPE FROM ORDERD WHERE ORDNO_D = @NO
) AS A WHERE PTYPE = 'S' GROUP BY PTYPE
DECLARE @DIS FLOAT
IF @CON >= 10
BEGIN
SELECT @DIS = 0.29
END
ELSE
BEGIN
SELECT @DIS = 0.39
END
DECLARE @AMT AS FLOAT
DECLARE @RAAMT AS FLOAT
-- 計算這筆訂單應該要多少錢
SELECT @AMT = ROUND((SELECT SUM(RBICE * RBQTY) * @DIS FROM ORDERD WHERE RBICE <> RBUPC AND ORDNO_D = @NO) +
(SELECT ISNULL(SUM(RBICE * RBQTY),0) FROM ORDERD WHERE RBICE = RBUPC AND ORDNO_D = @NO),0),
@RAAMT = (SELECT RAAMT FROM ORDERM WHERE ORDNO = @NO)
-- 如果算出來的錢跟訂單主檔不一樣,就寫到 TEMP TABLE
IF @AMT <> @RAAMT
BEGIN
--SELECT @NO,@AMT,@RAAMT
INSERT INTO @TEMP (ORDNO,AMT,RAAMT) VALUES (@NO,@AMT,@RAAMT)
END
-- 抓下一筆
FETCH NEXT FROM MYCURSOR INTO @NO
END
CLOSE MYCURSOR
DEALLOCATE MYCURSOR
SELECT * FROM @TEMP
GO
==============================================
下面這邊是簡單的寫法
目的是把 starwear 資料表中 hits 欄位(點擊數) + 100 之後再加 10 ~50 之間的亂數
(改這個是因為怕網站點擊數字太難看的關係)
SET NOCOUNT ON
DECLARE @no VARCHAR(10)
DECLARE MYCURSOR CURSOR FOR
--下面放你要跑迴圈計算筆數的SQL
select id from starwear
OPEN MYCURSOR
FETCH NEXT FROM MYCURSOR INTO @no
WHILE @@FETCH_STATUS = 0
BEGIN
--這邊放你要跑迴圈的 SQL
update starwear set hits = hits + 100 + (select top 1 id from starwear where id between 10 and 50 order by newid())
where id = @no
FETCH NEXT FROM MYCURSOR INTO @NO
END
CLOSE MYCURSOR
DEALLOCATE MYCURSOR
GO