iT邦幫忙

0

SQL 再請教一個遞增UPdate問題

UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0001'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0002'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0003'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0004'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0005'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0006'   WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0007'   WHERE [GsmpPtIndex] is null;

語法我用這樣
解果會一直到PAP_0482,共482個,依照從0001開始+1遞增
我這樣下語法變成全部 [GsmpPtIndex]這欄位都是 PAP_0001/images/emoticon/emoticon02.gif
然後找一下遞增的語法

UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0001'+1   WHERE [GsmpPtIndex] = 'PAP_0001' ;

因為我null已經變成PAP_0001了,我以為這樣可以

訊息 245,層級 16,狀態 1,行 1
將 varchar 值 'PAP_0001' 轉換成資料類型 int 時,轉換失敗。
```![/images/emoticon/emoticon02.gif](/images/emoticon/emoticon02.gif)![/images/emoticon/emoticon06.gif](/images/emoticon/emoticon06.gif)

我的欄位型別是 nvarchar(50),要先去改int嗎?還是?我SQL語法下錯

row_number 、convert 這個兩關鍵字給你參考,希望有所幫助。
wingkawa iT邦新手 3 級 ‧ 2019-02-11 14:53:19 檢舉
欸...我們看兩行就夠了

UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0001' WHERE [GsmpPtIndex] is null;
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0002' WHERE [GsmpPtIndex] is null;

開始前:
| GsmpPtIndex |
| null |
| null |
| null |

執行了第一行:
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0001' WHERE [GsmpPtIndex] is null;

| GsmpPtIndex |
| PAP_0001 |
| PAP_0001 |

第二行當然沒用啦,因為已經全部都不是null了!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

7
暐翰
iT邦大師 1 級 ‧ 2019-02-11 14:24:43
最佳解答

你的問題點:

UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0001'   WHERE [GsmpPtIndex] is null; // <--- 在這邊所有的null資料都已經被更新為PAP_0001
UPDATE [dbo].[TPAPQB01]SET [GsmpPtIndex] = 'PAP_0002'   WHERE [GsmpPtIndex] is null; // <--- 所以這時,已經沒有資料是null

另外我修改需求內容:
原先說法

解果會一直到PAP_0482,共482個,依照從0001開始+1遞增
我這樣下語法變成全部 [GsmpPtIndex]這欄位都是 PAP_0001

修改後說法

我自己嘗試得到錯誤結果:『全部 [GsmpPtIndex]欄位資料都是 PAP_0001』,我期望結果是從0001開始+1遞增一直到PAP_0482


解決方式

可以使用row_number + 流水號生成方式解決,如以下Script

--Update Logic Script
with cte as (
	select GsmpPtIndex,
		'PAP_' 
		+  right('0000'+convert(varchar(20),
			ROW_NUMBER() over (order by GsmpPtIndex)
		),4) as NewGsmpPtIndex
	from [TPAPQB01]
)
update cte set GsmpPtIndex = NewGsmpPtIndex;

--Check
select * from [TPAPQB01]

線上測試連結 : db<>fiddle

看更多先前的回應...收起先前的回應...
ted8224 iT邦新手 5 級 ‧ 2019-02-11 14:29:10 檢舉

是的我想得到這樣解果,他會一直到

GsmpPtIndex
PAP_0001
PAP_0002
PAP_0003
PAP_0004
PAP_0005
...

PAP_0482
暐翰 iT邦大師 1 級 ‧ 2019-02-11 14:31:47 檢舉

有482筆null資料,所以結果得到1~482,這樣不是符合你所要的嗎?

ted8224 iT邦新手 5 級 ‧ 2019-02-11 14:36:23 檢舉

不是結果得到,GsmpPtIndex 全部變成 PAP_0001
我語法好像沒下好樣子
https://ithelp.ithome.com.tw/upload/images/20190211/20109425PZ0S1d27bs.png

暐翰 iT邦大師 1 級 ‧ 2019-02-11 14:38:25 檢舉

解果會一直到PAP_0482,共482個,依照從0001開始+1遞增
我這樣下語法變成全部 [GsmpPtIndex]這欄位都是 PAP_0001

我修改需求內容一下,你應該是想說

我自己嘗試得到錯誤結果全部 [GsmpPtIndex]這欄位都是 PAP_0001,我期望的是依照從0001開始+1遞增一直到PAP_0482
ted8224 iT邦新手 5 級 ‧ 2019-02-11 14:40:50 檢舉

恩恩對,應該發問附上圖片比較好理解../images/emoticon/emoticon16.gif

暐翰 iT邦大師 1 級 ‧ 2019-02-11 14:50:52 檢舉

可以了,我更新解決方式在原本的回答 ted8224

ted8224 iT邦新手 5 級 ‧ 2019-02-11 15:09:09 檢舉

想請教一下這個語法
update row_number + 流水號生成
這算是進階SQL語法?
我直接把大大語法code貼上去就好了
謝謝

你可要真的了解人家幫你的地方在哪裏。
不要只是會抄而已。要明白為何需要這樣做。

直接將sql應用語法給你是很快就可以用。但如果無法了解其中的意思。
你下次還是會跟小a一樣,相同的處理方式,不同的參數又在問一次。
無限的鬼打牆。

現在是有人幫你直接寫好sql碼給你用。但下次呢?
雖然我並不太建議在sql上用程式的應用語法來跑就是了。

暐翰 iT邦大師 1 級 ‧ 2019-02-11 15:15:24 檢舉

是進階SQL語法
跟yoching大大說的一樣,建議先以關鍵字查詢背後邏輯,看完有不懂的地方再系統整理發問,這樣吸收會比較好。

ted8224 iT邦新手 5 級 ‧ 2019-02-11 15:21:50 檢舉

我連關鍵字都找不好
我找"SQL update遞增"下去找這樣..
我不熟這進階語法

ted8224
那個是隨機應變的進階語法..
基本上是找不到@@..

暐翰 iT邦大師 1 級 ‧ 2019-02-11 15:26:48 檢舉

我記得你是主要使用C# 這類OOP語言
學SQL會有一點陣痛期,因為它要以單位為集合角度來思考

舉例

  1. row_number它是對結果集的輸出進行編號的方法,因為編號需要有個排序,所以需要order

  2. 使用right是因為你需要0001,0002這種流水號資料,那麼所以用'0000' + 你的數字,再從右邊取四碼方式得到流水號。

  3. 另外使用CTE是方便查詢完需要的結果後,再做更新。

ted8224 iT邦新手 5 級 ‧ 2019-02-11 15:33:39 檢舉

暐翰
謝謝你.
純真的人對阿我找好久有點怪怪,run下去不是我要的所以上來發問.

圓頭人 iT邦研究生 5 級 ‧ 2019-02-12 11:09:58 檢舉

哇~~謝謝 暐翰 大大
原來CTE可以這樣用啊

0

說真的,我還真不知道該從什麼地方來去指導你了。
只給你幾句話當重點好了:

1.不要拿sql當程式設計用。sql並不會一筆一筆跑的。
2.不要用字串欄位做相加的動作。會被重新處理為數值型態造成問題的。
3.再加油吧,你的問題著重在第一點。把問題簡單化一下。不要將sql語法當萬能使用。

PPTaiwan iT邦好手 1 級 ‧ 2019-02-12 11:16:52 檢舉

"不要拿sql當程式設計用。sql並不會一筆一筆跑的。"

不太理解你這說法是?? 什麼情形下 SQL 不會一筆一筆來跑呢??

@PPTaiwan
所以?你認為資料庫是一筆update完再處理下一筆??

換言之反問你,什麼情況下sql語法是一筆一筆跑的。
(有這樣的處理方式,但那需要有唯一key的情況下才能辦到)

我要發表回答

立即登入回答