2010年8月27日 星期五

如何在SQL Server 資料庫中 找出符合你的關鍵字的Store Procedure

要讓你在資料庫中,找出符合某關鍵字的 Store Procedure,要怎麼去完成呢?

以前龐統曾獻三計給劉備奪川蜀,現在也有三種方法來取 Store Procedure。

下計:
一個一個點開 Stroe Procedure,並用搜尋的方式,將每個符合你關鍵字的 Store Procedure都記錄下來。

中計:
使用 SQL Server 提供的「產生指令碼」功能,並將所有 Store Procedure都點選,匯出成一個檔案。開啟這檔案,用搜尋的方式找到符合你關鍵字的 Stre Procedure。

上計:
善用SQL Sever 提供的 view :INFORMATION_SCHEMA.ROUTINES 來完成。

劉備認為上計過急,下計又太緩,故依中計而行。而我早已被 user 逼急了,所以應該會用上計吧!

在資料庫裡,每一支 Store Procedre 或 Function ,都會有對應的一筆 INFORMATION_SCHEMA.ROUTINES紀錄。而這 view 裡的欄位 ROUTINE_DEFINITION 就保存著目前使用者所定義的程式碼。如果今天你想要取得符合某個關鍵字的所有 Store Procedure,那只要在 INFORMATION_SCHEMA.ROUTINES 查詢 ROUTINE_DEFINITION 欄位就可以達成。如果你想更進一步去限制只要查詢Store Procedure類型,那可以在 ROUTINE_TYPE 設定條件為 「PROCEDURE」。(目前有兩種類型:PROCEDURE / FUNCTION)

以下是個範例,找出所有關鍵字為 delete prog_base 的 Store Procedure:
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%prog_base%'
AND ROUTINE_TYPE = 'PROCEDURE';

INFORMATION_SCHEMA.ROUTINES是系統預設提供的 view,換言之,他也是從某些現有的資料表或 view 萃取資料而來。所以,我們當然也可以不透過這 view,直接去從資料表抓。以下,是更原始些的語法,而效果也是一樣。

SELECT distinct sys.sysobjects.name, sys.sysobjects.type
FROM sys.sysobjects INNER JOIN syscomments 
ON sys.sysobjects.id = sys.syscomments.id
WHERE sys.syscomments.text LIKE '%prog_base%' 
AND sys.sysobjects.type = 'P'
ORDER BY sys.sysobjects.NAME

如果要考慮彈性的話,可以考慮使用 syscomments 的使用方法,因為他可以支援的類型,不侷限於 Stroe Procedure , Function,他還支援 Table , View 。所以使用 syscomments 是一個比較完整的解決方案。

而近來自己實際比較了使用 INFORMATION_SCHEMA.ROUTINES 與 syscomments 查詢結果,發現兩邊查出來的資料竟然會不一致,細究原因,原來是 INFORMATION_SCHEMA.ROUTINES 裡的 ROUTINE_DEFINITION 欄位,只支援到長度 4000,換言之,如果有一個 Store Procedure 寫了超過 4000 字以上的程式碼,剛好你的查詢關鍵字又落到 4000 字以後,這樣使用 INFORMATION_SCHEMA.ROUTINES 就查不出資料了。發現了這原因後,就更建議使用 syscomments 來完成你的需求了。詳細原因可參考 Madhivanan 部落格的介紹。他建議若要完整取得 ROUTINE_DEFINITION 欄位 裡的資料,要使用以下方式:

--Method 1
select object_definition(object_id('your_procedure'))

--Method 2
EXEC sp_helptext 'your_procedure'

2010年8月24日 星期二

在 JavaScript 裡,知道 === 與 == 的區別嗎?

印象中,以前有遇過這問題,但當下認為他們是一樣的,所以也就沒有很認真去區分他們間的差別。但今天在看 jQuery 的原始碼時,發現這些老外都喜歡用 ===  而不用 ==,難到,真的只是因為老外比較長這原因而已嗎?

而我在 devguru 找到老外比較長的原因了。

一般在寫 JavaScript 時,我們「等號運算子(==)」的左右兩邊,你可能偶而會發現,如果有一個變數,他的值是整數,但如果在等號運算子的另一邊用字串來比較,有可能會通過。舉個例子來說:

var v=5;
if ( v=="5")
  alert('the same');
else
  alert('not the same');

這程式執行的結果,會跑出 「the same」出來。原因是你使用 == 運算子時,他會試圖自動去幫你作轉型的動作,以符合懶人的期望。但這一懶,卻也跑出了些潛在的問題。

第一,雖然程式幫你作了自動轉型來比較,但你可能已經誤用或誤會了這個變數他原本所宣告的變數型態,現在他包容了你,但不保證當你的程式變肥之後,日後在型態處理上吃了一記悶棍。

第二,是效能問題。如果要讓程式去幫你作自動轉型的動作,則他必須要多花一些額外的時間將所有型態一一去跟你目前的變數比較,這動作會比你一開始就直接講明兩邊都是要同樣型態會來得花時間。

所以,如果要讓自己程式寫得嚴謹,使用嚴格的等號運算子(===)是比較建議的。而他的雙胞胎兄弟,則是 !==,就請大家自個兒舉一反三了。

個人在 stackoverflow 論壇看到一篇很詳盡的介紹,很推薦去看他那篇說明,或找關鍵字 strict equal operator 搜尋更多其他文章。

參考:
01:http://www.devguru.com/Technologies/ecmascript/quickref/comparison_operators.html
02:http://stackoverflow.com/questions/359494/javascript-vs-does-it-matter-which-equal-operator-i-use
03:http://www.webreference.com/js/column26/stricteq.html

2010年8月22日 星期日

ImageButton 似乎跟 Repeater、DataList、GridView 不合

最近為了讓網頁變得花俏,所以每個按鈕都有專屬的一張圖使用,不過是按鈕放張圖而已嘛~
但跑出的結果,卻讓人噴飯 >_<
「無效的回傳或回呼引數」,這就是美麗的代價嗎?

我本來是要做上圖的功能,透過 Repeater ,並在每一個資料列中放「刪除」按鈕,執行刪除後就會重新更新一次資料。

所以在 Page_Load( ) 事件,就沒有將繫結 Repeater 的動作包在 if(!IsPostBack) 的判斷式中。我曾經試著用錯誤畫面裡的建議,將 <%@ Page 裡的  EnableEventValidation 屬性設為 false 。雖然這動作可以避免產生「無效的回傳或回呼引數」錯誤訊息,但是原先針對「刪除」按鈕的事件動作卻變成不會被觸發,真是折磨人啊!

我決定,要去抓個墊背來試試...
我就棄 ImageButton 改用 Button 試試。發現他一樣有這種現象。
接著測試  LinkButton ,成功了!這三個Button 兄弟,總算有一個有出息,沒有全軍覆沒。

可是,使用 LinkButton,有沒有辦法放圖呢?於是,把腦筋動到他的 Text 屬性,把 <img src=btn_delete2.jpg border=0 /> 寫到 Text 屬性裡,發現竟然可以哩~

今天發生的這種現象,並非只存在於 Repeater ,DataList 、 GridView 也是都這樣。為何以前自己沒注意到有這現象發生,這就在於繫結資料的動作,以前我都習慣將他放到 if(!IsPostBack) 判斷式裡,還有另一種可能,就是 ... 程式寫太少啦,你這懶鬼 !!!

測試檔案下載

網路上相同受害者