[如何學習寫程式] #10 - 練習由線索去找解答或可行的作法,而不是老買伸手牌。

我們經常會對新手說:寫程式前一定要先思考,意即於此。設計決策只能透過不斷的思考訓練才能進步,坊間的書雖然也會講設計的最佳作法 (Best Practices),但不會告訴你這些作法是如何發展而來的細節資訊,這些細節只能透過學習的人一步一步的實作來感受,也因此這些設計決策是經驗累積而來的。

又是一篇有感而發的文,但這次的來源是這裡

有部份學習程式的人,總是很容易犯一個毛病,就是很愛買伸手牌程式 (表示很愛叫別人解問題,自己卻只想坐享其成),每個論壇上多多少少有這種討論串,而不賣 (即不給解答) 的話,馬上擺臉色給你看,或是用文字來嘲諷論壇上的人,當然這種行為是非常令人不齒的,我也針對這種行為寫過文章

但不能否認,確實會有一些努力想要尋求解答的人,這時候我們多半會以引導的方式來進行討論,目的是讓學習的人能夠自己去發掘答案,或是自己學習找尋最佳作法的能力,這一系列的設計決策 (Design Decision) 會影響你日後在撰寫程式時的思考力,我們經常會對新手說:寫程式前一定要先思考,意即於此。設計決策只能透過不斷的思考訓練才能進步,坊間的書雖然也會講設計的最佳作法 (Best Practices),但不會告訴你這些作法是如何發展而來的細節資訊,這些細節只能透過學習的人一步一步的實作來感受,也因此這些設計決策是經驗累積而來的。

以我看的那篇文章為例,他的問題是這樣的:

小弟有參考Lolota Lee得一篇解決方法如下:
//================================================
create function Split (
@StringToSplit varchar(2048),
@Separator varchar(128))
returns table as return
with indices as
(
select 0 S, 1 E
union all
select E, charindex(@Separator, @StringToSplit, E) + len(@Separator)
from indices
where E > S
)
select substring(@StringToSplit,S,
case when E > len(@Separator) then e-s-len(@Separator) else len(@StringToSplit) - s + 1 end) String
,S StartIndex       
from indices where S >0
然後用下列方式取
select  String, COUNT(string)as 次數  from Split('aaa,b,cccc,b,dd,e,ffff,g' , ',') group by string
//================================================================
可是對象如果是text的行態欄位,不知道要如何放入??
因為我的長度很長.....

這個問題已經有 Reference 了,但是他的問題不在沒有 Reference,而是不知道從哪去找解答。由這個問題陳述,我們可以得知原 Reference 是使用 varchar,但他想要用 text (線索1),這時我們第一個反應會是去找 text 是什麼,以及它的用法與限制,因為 text/ntext/image 是屬於 BLOB 型別,所以它只能使用 DATALENGTH, READTEXT, PATINDEX, SUBSTRING, UPDATETEXT, TEXTPTR, WRITETEXT 與 TEXTVALID 等 T-SQL 函數 (線索2)。

而在 Reference 中,我們可以看到它用了 LEN 來計算來源字串的長度,但若來源字串是 text/ntext 的話,LEN() 會無法使用,但我們由線上手冊查到可以使用 DATALENGTH 來取 text/ntext 的長度,故我們可以把 len(@StringToSplit) 改成 DATALENGTH(@StringToSplit),然後把函數宣告中的 @StringToSplit varchar(2048) 改成 @StringToSplit ntext,改變的指令如下:

create function Split (
   @StringToSplit ntext,
   @Separator varchar(128))
returns table as return
with indices as
(
   select 0 S, 1 E
   union all
   select E, charindex(@Separator, @StringToSplit, E) + len(@Separator)
   from indices
   where E > S
)
select substring(@StringToSplit,S,
   case when E > len(@Separator) then e-s-len(@Separator) else DATALENGTH(@StringToSplit) - s + 1 end) String
   ,S StartIndex      
from indices where S > 0

然後把它送到 SQL Server 中跑,傳入一個 ntext 型態的字串,你會發現它可以 work:

image

經過由問題內容去找關鍵字,透過線上手冊的協助,是不是就可以把問題給解掉了呢?

也許初學者沒辦法很快的找到解答,但是一開始都不會很快,只要慢慢熟悉熟練後,相信你的解題速度會比一開始快非常多。