Feb 27, 2010

Nhật ký tháng giêng

29 Tết về tới nhà. Y hẹn, tối lên nhà vợ bạn Nghị. Có Trọng Còi, Còi lõi, Huy nhỏ. Nhậu say chúi lúi tới 11h mới về tới nhà.

30. Sáng làm heo, làm xong ngồi lai rai với anh Hiển, cậu 9. Tối xuống cầu nhậu với anh em trong xóm. Năm nào đám thanh niên cũng tụ tập ở bên kia đầu cầu đốt lốp xe, uống rượu chay và bắn pháo tự chế làm bằng đá đèn. Gần 12h mới về tới nhà đón giao thừa.

Tối mùng 1 tết vào nhà Bửu đại ka, có đầy đủ anh em: Dũng mác, anh Thuận, anh Công, 8 Long...Chạy về tới nhà thì ngã ra giường, lát sau nôn ói mữa :D

Mùng 2 tết chạy lòng vòng thị trấn. Không có cuộc nhậu nào nhưng cả ngày đi chúc Tết uống không ít. 333, Ken, rượu nếp, rượu gạo, XO...chẳng thiếu thứ gì. Nghĩ thương cho cái bụng :D

Mùng 3 Tết đi họp lớp. Năm ngoái 8h sáng đi 1h sáng mùng 4 về, dắt xe lên thềm nhà té đúng 3 lần. Năm nay cũng nhậu tẹt ga. Vậy mà không say. Thầy đưa máy bảo chụp hình thầy trò các khóa cứ zoom con bé Lan mà bấm, mới hay tật mê gái ...đẹp không bỏ được. 8h tối về, cả nhà ồ lên ngạc nhiên (sao năm nay không say lại về sớm). Thiệt là mắc cỡ quá đi !

Mùng 4 tết ghé qua trường họp diễn đàn, 9 năm rồi mới lại vào trường. Ngày xưa đi học mỗi năm mùng 4 gặp mặt sv không bao giờ thèm về trường (tại chổ đó phát tiền chớ hok phát...bia). Gặp mấy anh K.94 họp khóa, quen được vài người. Có cả Thầy Trực. Anh Toàn kéo vào, thế là hiếp được ...vài lon bia. Trưa lại đi...họp lớp, lớp 12A. Ngày xưa đi học chỉ toàn chơi với mấy đứa con gái 12A thôi. Bí thư chi đoàn 12A vẫn xinh như ngày nào. Nghe nói chiều phải chạy về vì gia đình bạn trai ở Nha Trang ra xem mắt. Chửi bọn con trai 12A ...bất lực, để cho gái đẹp đi lấy chồng xa. Kéo nhau đi luyện sư tử hống, ai ngờ nguyên 1 dãy kara toàn bọn cùng khóa: 12A, 12E, 12G...Chạy dọc hành lang uống từ lớp này cho tới lớp khác. May mà hok say.

Mùng 5, xuống nhà bạn Nghị, thằng bạn sáng dậy sớm đi bắt cá. Cua đá vàng ươm, cá bộp ly ti như ngón chân cái nấu lá giang. Mồi ngon không uống thì ...phí. Say! Tối về anh em trong xóm tụ tập nhà Phong. Bảo Chi, Quỳnh, Tâm lên chơi, chạy về nhà chút xíu chạy lại đã thấy 6 chai SG để trước mặt...

Mùng 6, đám hỏi bạn Huy. Chạy qua Ân Tín. Uống vừa phải, trốn về sớm, rủ Trọng Còi vào nhà thầy Thọ dọn rượu. Nó mất hồn nhảy xuống xe qua xe thằng Kiên về mất hút. Một ngày tỉnh táo hiếm hoi.

Mùng 7, sắp vác balo đi thì Duy đầu bò gọi điện. Nó mới trốn vợ từ ĐăkNông mò về lúc sáng. Một hai phải xuống. Ừ thì xuống ! Ông già nó bảo chai Red này tao để tiếp khách quý... Chút xíu nữa là quá chén. 5 giờ chiều lên xe vào SG.

Mùng 8, anh Toại điện bảo qua nhà làm ...chút. Mới vào mệt quá hok qua được. Ngày không rượu bia. Ôi, mới biết hạnh phúc nhiều khi rất đơn sơ...

Mùng 9 đi làm. Chiều Trọng Còi điện bảo mới vào, có đem theo mớ ngóe. Ngóe nấu cháo thì hết chê. Gặp cả đám kiến trúc, xử hết canh Bàu đá mới đem vào, hát hò ỏm tỏi, 1h mới về tới nhà.

Mùng 10...8h tối Huy tiễn vợ qua Malay, thằng con buồn gọi điện rủ ...nhậu. Ừ thì hôm trước đám hỏi mầy tao không uống, tối nay tao qua, sẳn ghé anh Toại lì xì thằng cháu, hôm qua mệt quá không qua được. 3 anh em ...làm chút. Bỏ học bữa đầu...lấy hên.

Mùng ...11. Họp đầu năm, anh Phúc đem vào canh Rượu Bầu đá 5 lít. Họp với nhau có 30 phút, họp với Bầu đá tới hơn 2 tiếng.

Mùng ...12. Em Toàn nt: nhậu hok Sir ?. Trả lời: sir đang ngồi trong lớp, 9h sir mới về. Ai ngờ nó mò xuống tới quận 2, dẫn theo cả thằng Vỹ. 3 anh em ngồi lề đường Trần Não tới 1h sáng oải quá mò về trước.

13. Thứ 6. Hết Tết còn xuân. Công ty tổ chức sn cho anh chị em trong tháng 2. Tối nay lòng đã quyết lên GV, không uống cf thì đi nhậu, không đi với người này thì ngồi với người khác. Bạn Lễ khoe có canh rượu Củ Chi ngon lắm. Đang buồn mầy, đừng có hù tao. Nhậu bánh tráng với chả trứng gà.

14. Hôm nay. Chiều anh Bắc điện bảo mai lên Hóc Môn dự sn tròn năm của thằng con. Ngày đầy tháng nó, ra tới Xuân Lộc mới biết trong túi không còn đầy trăm bạc, ăn nhậu đã rồi thong lên xe mò về. Giờ tới thôi nôi nó không thể không lên rồi. Nhưng biết mua gì giờ ?

Giá mà có má ở đây, sáng mai ngủ zậy thế nào cũng có thứ xách đi, khỏi cần lo nghĩ...

Anh Bắc nói mai có anh em quê mình đông vui lắm ... Không biết chỉ ngồi...ăn thôi thì có được yên không ?

Feb 26, 2010

6:09 PM - No comments

Giấc mơ trưa




Em nằm em nhớ (A)
Một ngày trong veo (A), một mùa nghiêng nghiêng (Bm)
Cánh đồng xa mờ (F#m), cánh cò ngiêng cuối trời (E)

Em về nơi ấy (A)
Một bờ vai xanh (A) một dòng tóc xanh (Bm)
Đó là chân trời (F#m) hay là mưa cuối trời (E)

Và gió theo em (A) trôi về con đường (F#m)
Và nắng theo em (A) trên dòng sông vắng (F#m)
Mùa đã trôi đi (Bm) trong miền xanh thẳm (E)
Người đã quên đi (Bm) những lần em buồn (E)

Từng dấu chân xưa (A) trên đường em về (F#m)
Giờ đã ra hoa (A) những cành hoa vắng (F#m)
Người đã đi qua (Bm) những lời em kể (E)
Này giấc mơ trưa (Bm) bao giờ em về (E)
Một tiếng chuông chùa (A)

Feb 25, 2010

Feb 23, 2010

Nhàn đàm về uống rượu

Phân loại

Những kẻ uống rượu trong thiên hạ theo tớ đều có thể được xếp vào 1 trong 4 cấp sau đây:

Loại thứ nhất là loại uống rượu theo kiểu Chí Phèo, say lên là phá phách xóm làng, đập đánh vợ con, hiếp người đốt nhà đúng phong cách đệ tử lưu linh. Uống rượu kiểu này tớ cho là hạ hạ cách. Cần bỏ gấp.

Loại thứ hai là loại hay ham vui quá chén ở các dịp hiếu hỉ cúng lễ, bạn bè gặp mặt, cuối tuần tụ tập...đôi khi to tiếng cãi vã tranh luận với bạn nhậu nhưng nói chung ít có nguy cơ phương hại cho xã hội. Ít chứ không phải không có, ví như uống say chạy xe tự gây tai nạn cho mình hoặc cho người khác... đó là chưa kể đến việc chắc chắn sẽ phương hại đến bản thân (sức khỏe, thời gian, tiền bạc...) . Kiểu uống rượu này tớ xếp vào hàng hạ thượng cách. Cũng nên bỏ.

Loại thứ ba là loại uống vào những dịp đặt biệt phải uống và không thể không uống. Tuy nhiên loại người này luôn uống vừa phải, biết tự kiềm chế, biết tự chủ mình, không khi nào để mình say (say theo nghĩa sinh học). Kiểu uống này là thượng hạ cách. Bỏ cũng được mà không bỏ cũng được.

Loại cuối cùng là loại mượn rượu làm phương tiện để "say" theo nghĩa đẹp nhất của từ này. Uống và "say" như cái say của Nguyễn Khuyến, của Lý Bạch. Đó là thượng thượng cách. Trong cõi đời này có mấy ai làm được ?

Say và mục đích của việc uống rượu
:

Người uống rượu mấy ai hiểu được nghĩa của từ say, cũng như mấy ai hiểu được mục đích của việc uống rượu ?

Cá nhân tớ cho rằng uống rượu là phải say. Không phải cái say té ngã, cái say ói mửa thô thiển sinh học mà là cái say của tình người, tình anh em, tình bằng hữu, cái say của con người với đất trời...Nếu không tìm được cái say đó thì uống bao nhiêu rượu cũng thừa thải, uống bao nhiêu cuộc cũng vô nghĩa. Say để tiếp thông và thấu hiểu, đó chính là mục đích của việc uống rượu. Vậy thì thấu hiểu cái gì ? trước hết là để thấu hiểu bản thân mình, sau đến thấu hiểu tha nhân, sau cùng là thấu hiểu cả lẽ đời, đất trời, vũ trụ...Phụ nữ ít ai thông cảm với người đàn ông ở việc uống rượu là vì bản thân họ, được Thượng đế ban cho đặt quyền không cần thấu hiểu ai cả, trái lại người khác phải có nghĩa vụ thấu hiểu họ. Đàn ông uống rượu, hiểu được từ "say" đã hiếm, đạt được cái say đó mà dẫn tới sự thấu hiểu lại càng hiếm, đương nhiên lúc đó việc uống rượu của họ cũng được xếp vào hàng thượng thượng cách.

Cái hại của việc uống rượu:

Người uống rượu nếu không đạt đến thượng thượng cách thì chưa phải uống rượu. Nhưng có mấy người đạt đến thượng thượng cách ? Có một người (vâng, lại là phụ nữ) đã nói với tớ thế này: "Đàn ông uống rượu chẳng thằng nào giữ được tư cách". Điều đó chẳng sai, chỉ vì phần lớn chúng ta hiện giờ uống rượu theo kiểu hạ hạ cách và hạ thượng cách, có uống cả đời thì cũng chỉ ở mức đó mà thôi. Nghĩa là chúng ta chưa bao giờ biết uống rượu nhưng vẫn mang tiếng là những kẻ say rượu.

Kẻ bỉ phu uống rượu vào thì ngứa ngáy tay chân, hiếp người đốt nhà không bàn tới làm gì. Người có học cũng đâu có hơn gì, rượu vào thì lời ra. Thánh nhân nói trăm câu cũng có câu không đúng, huống chi người phàm, uống rượu vào nói năng bạt mạng, giành nhau mà nói, nghĩ đâu nói đó. Kẻ bất tài có rượu vào thì nói dốc nói dóc, nói để khẳng định mình không thua kém thiên hạ. Người có tài lúc tỉnh táo còn giữ được chút kiêm nhường, rượu vào ai cũng cho mình là nhất, thiên hạ là bét, chẳng ai chịu ai. Kẻ sĩ phu bất mãn lúc tỉnh còn có giữ ý tứ kiềm nén, say rồi nghĩ đâu nói đó, chỉ khổ cái miệng hại cái thân, thần khẩu hại xác phàm. Bậc trưởng thượng bình thường cẩn trọng từng lời ăn tiếng nói, cử chỉ hành động, khi quá chén chỉ cần một câu nói lỡ, một cử chỉ thiếu trang nghiêm là thanh danh đã kịp vấy bẩn. Riết rồi thành quen, tỉnh cũng như say, say cũng như tỉnh, tính cách say bén rễ vào tính cách tỉnh, con người say bén rễ vào con người tỉnh. Đó chính là cái hại lớn nhất của bọn có học uống rượu vậy.

Tự nhìn nhận:

Tớ 17 tuổi biết uống rượu, không sớm không muộn. Trong 10 năm trải qua trăm cuộc: độc ẩm, đối ẩm, quần ẩm và cả loạn ẩm, đủ cả. Một lần giận bạn suýt đánh nhau, một lần chạy xe tự gây tai nạn cho mình, rất nhiều lần giận hờn hay điện thoại phá phách bạn bè trong cơn say và vô số lần để cho phụ mẫu phải phiền lòng...Nghiêm túc nhìn nhận, có uống nữa cũng chỉ đạt đến hạ thượng cách là cùng, chỉ rước cái hại vào thân. Có lẽ cũng là lúc nên dừng rồi chăng ?

Feb 10, 2010

9:48 PM - No comments

Sự im lặng vĩnh cửu

Sự im lặng vĩnh cửu
(Chẳng biết gọi là văn xuôi hay thơ nữa)

Có khi nào,
Em thấy anh tệ hơn cả Trương Chi
Khi chỉ biết giấu mình trong nỗi nhớ
Và lén lút yêu em bằng tình yêu rất dỡ
Tình yêu không lời...

Yêu thì phải nói cho to
Đã có một tựa phim như thế
Yêu là phải tuyên thệ
Rằng anh yêu em ! Thiên thu !

Trời ơi !
Em có biết đâu
Khẩu ngữ muôn đời vẫn là phương tiện giao tiếp thấp hèn nhất
Chỉ được nhớ đến khi người ta cảm thấy chật vật
Trong việc thể hiện mình bằng những kênh giao tiếp cao hơn.

Khi yêu có nhất thiết phải hét thật to ?
Em thấy đấy,
Trương Chi yêu Mỵ Nương chỉ bằng một tiếng sáo.
Nguyễn Huệ yêu Ngọc Hân qua một nhánh đào tươi...

Anh yêu em
Không phải bằng lời.
Không phải bằng nhạc.
Không phải bằng thơ.

Anh yêu em
Và mãi miết đợi chờ.
Bằng sự im lặng vĩnh cửu.

Feb 9, 2010

1:09 AM - 1 comment

Change Visual Studio 2008 Product Key

Today I open my Visual Studio 2008 and it throws out this message: "The evaluation period for Visual Studio trial". Of course my V.S has expired.

I google and find out this solution. Share this for who don't want to pay any pence for Gates. Yeah, he's too rich :D

Go to Add/Remove and select Visual Studio, chose Change/Remove.
Change your produce key to: XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT

Good luck !

(:D Just a joke, in all cases, I encourage you buy a valid key for your software produce. 'Cause we're coders, right ?)

Feb 7, 2010

11:45 PM - ,, 1 comment

Disable CallOut Validator

AjaxToolkit ValidatorCalloutExtender control provides you a new (of course, a nice) way to display your validate message. Although still have some inconveniences but it's worth to try :))

One of inconveniences is when you disable your target validator control by JavaScript (4 example, call ValidatorEnable(targetValidateControl, false)) the callout validator popup still shows every time you focus to the control.

Here's the solution to fix this issuer :

1.Set CSS class for ValidatorCalloutExtender:

HTML Code:

<style id = "style1" type="text/css">
.CustomValidator
{
position: relative;
margin-left: -80px;
margin-top: 8px;
display: inherit;
}
</style>
<ajax:ValidatorCalloutExtender ID="ProductIncrementVE" runat="server"
TargetControlID="ProductIncrementValidator"
HighlightCssClass="validator"
WarningIconImageUrl="~/img/blank.gif"
CssClass="CustomValidator">


</ajax:ValidatorCalloutExtender>

2 . Use JavaScript to alter this CSS class when needed. Set display = none:

Mã:

function alterDisplay(type) {
var styleSheet, cssRule;
if (document.styleSheets) {
styleSheet = document.styleSheets[index1];
if (styleSheet) {
if (styleSheet.cssRules)
cssRule = styleSheet.cssRules[index2]; // Firefox
else if (styleSheet.rules)
cssRule = styleSheet.rules[index2]; // IE
if (cssRule) {
cssRule.style.display = type;
}
}
}
}

Note: the index1 and index2 may be difference from pages, it's up to your declaration. You can use IE debugger to find our the correctly index.
Hope they fix this problem in next release.

Feb 4, 2010

Về đi em...

Giận nhau hơn 30 ngày, nhớ em tan nát mà chẳng biết cách nào làm lành trở lại. Tính mình bảo thủ và cứng nhắc đến mức cực đoan, cho dù phải gạt nước mắt nhìn thấy những điều quí giá dần vuột khỏi tầm tay thì nhất cũng quyết không chịu xuống nước, không chịu thừa nhận điều quan trọng nhất: mình đã thương em và vẫn thương em. Vẫn biết vậy nhưng không thể không vậy...

Thế rồi mình để status link tới bài hát này.
Thế rồi em gởi sms: "Cảm ơn anh nha, bài hát hay lắm!"
Thế rồi nói chuyện lại với nhau.
Thế rồi một lần nữa, lại xa nhau.
Lần này không phải là 30 ngày. Lần này là 2 tháng. Lần này không còn đong đếm được nữa. Lần này có thể là mãi mãi...

Mượn Clip của ai đó trên Youtube. Nghe để nhớ về 1 thời, nghe để nhớ về 1 người...



Về đi em (Dm)làng quê cũ (Gm)
Có con sông(C) xưa vỗ về(F)
Về ôm (Dm)vai Mẹ yêu dấu (Gm)
Đế được khóc (F)như đứa trẻ thơ (A7)
Đế quên đi (Gm)năm tháng bơ vơ (F)
Mình em (Gm)giữa phố đông không nhà(Dm)
Bủa vây (F) em nghèo đói xa (A7)hoa dối lừa(A7)
Để quên đi (Gm)một phút giây lỡ làng(F)
Đời em (Gm) trong trắng như hoa (Dm)
Về đi em (F) cô gái (A7) thơ ngây của làng ta(Dm)

Về bên (Dm) dòng sông thơ ấu (Gm)
Có anh trai (C) quề vẫn chờ (F)
Đàn vịt xiêm (Dm) còn ngơ ngác nhớ (Gm)
Chị Tấm (F) xinh tươi ngày xưa (A7)
Bàn tay (Gm) em duyên dáng đong đưa (F)
Chợt sông (Gm) nhớ bóng em đi về (Dm)
Tình quê (F) mái lá đơn sơ (A7) vui câu hò (A7)
Để quên đi (Gm) thành phố kia xa lạ (F)
Về vui (Gm) yên ấm nơi quê nhà (Dm)
Về đi em (F) cô gái (A7) thơ ngây của làng ta(Dm)

Feb 3, 2010

9:58 PM - , No comments

Validate with OnClientClick

Using an OnClientClick function in submit button like:

<asp:Button ID="btnFinish" runat="server" SkinID="ButtonWidth50" Text="Finish" OnClientClick="return CheckForm()"/>

maybe lets your validate controls do not work correctly.

When the CheckForm() returns a true value, your page goes thought to sever and does not execute validate functions.

Solution:
call Page_ClientValidate() function to force controls do there's validate tasks before goes to another processing.

function CheckForm() {
var result = true;
result = Page_ClientValidate();
if (result){
// Do your task here
}
return result;
}

Feb 2, 2010

10:02 PM - 9 comments

Giới thiệu về stored procedure trong MySQL (P.7)

Con trỏ trong Stored Procedures

MySQl hỗ trợ con trỏ trong cả stored procedures, hàm và triggers. Con trỏ được dùng để duyệt theo từng hàng bảng kết quả trả về từ câu truy vấn và xử lý các hàng đó. Tất cả những version sau MySQL 5.x đều hỗ trợ con trỏ với các thuộc tính sau:

* Read only: bạn không thể update con trỏ
* Non-scrollable: con trỏ chỉ có thể di chuyển theo 1 hướng và không thể bỏ qua bất cứ 1 hàng nào, trượt tới hay trượt lùi trong bản kết quả.
* Asensitive: bạn nên tránh update 1 table trong khi vẫn đang mở con trỏ trong chính table đó. Nếu không bạn sẽ nhận được những kết quả không mong đợi

MySQL hỗ trợ các phát biểu sau khi làm việc với con trỏ:

Khai báo 1 con trỏ với phát biểu DECLARE

Mã:
 DECLARE cursor_name CURSOR FOR SELECT_statement;
Mở con trỏ bằng phát biểu OPEN. Bạn phải mở con trỏ trước khi duyệt qua bất cứ dòng nào trong bảng kết quả:

Mã:
 OPEN cursor_name;
Nhận dữ liệu ở dòng hiện tại trong bản kết quả và di chuyển con trỏ đến dòng kế tiếp bằng phát biểu FETCH:

Mã:
 FETCH cursor_name INTO variable list;
Cuối cùng, đóng con trỏ để vô hiệu hóa và giải phóng bộ nhớ. Sử dụng phát biểu:

Mã:
CLOSE cursor_name;

Một điểm quan trọng khi làm việc với con trỏ là bạn nên sử dụng điều khiển NOT FOUND để tránh gặp phải lỗi “no data to fetch”. Chúng ta sử dụng 1 ví dụ nhỏ dưới đây để demo về con trỏ:

Mã:
DELIMITER $$
DROP PROCEDURE IF EXISTS CursorProc$$
CREATE PROCEDURE CursorProc()
BEGIN

DECLARE no_more_products, quantity_in_stock INT DEFAULT 0;
DECLARE prd_code VARCHAR(255);
DECLARE cur_product CURSOR FOR
SELECT productCode FROM products;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_products = 1;

/* for loggging information */
CREATE TABLE infologs (
Id int(11) NOT NULL AUTO_INCREMENT,
Msg varchar(255) NOT NULL,
PRIMARY KEY (Id)

);

OPEN cur_product;
FETCH cur_product INTO prd_code;
REPEAT
SELECT quantityInStock INTO quantity_in_stock
FROM products
WHERE productCode = prd_code;
IF quantity_in_stock < 100 THEN
INSERT INTO infologs(msg)
VALUES (prd_code);
END IF;
FETCH cur_product INTO prd_code;
UNTIL no_more_products = 1
END REPEAT;
CLOSE cur_product;
SELECT * FROM infologs;
DROP TABLE infologs;
END$$
DELIMITER;

Stored procedure này khá đơn giản và có thể thay bằng truy vấn SQL. Chúng ta chỉ sử dụng cho mục đích demo cách thức làm việc của con trỏ

Ta dùng con trỏ để làm việc với table products. Nếu số lượng trong kho của product nhỏ hơn 100, tiến hành ghi lại log trong 1 bảng tạm và sau đó select tất cả các sản phẩm để in ra trong 1 màn hình.

Nhớ là bạn phải khai báo con trỏ trước tiên và sau đó khai báo điều khiển NOT FOUND, nếu không bạn sẽ gặp phải lỗi.

10:00 PM - No comments

Giới thiệu về stored procedure trong MySQL (P.6)

Vòng lặp trong Stored Procedures

Ngôn ngữ lập trình MySQl stored hỗ trợ phát biểu vòng lặp cho phép bạn thực hiện các lệnh lặp. Các kiểu vòng lặp được mô tả lần lượt dưới đây:

Vòng lặp while

Cú pháp của vòng lặp while:

Mã:
WHILE expression DO
Statements
END WHILE
Đầu tiên, vòng lặp while kiểm tra biểu thức điều kiện, nếu điều kiện có giá trị true thì chương trình sẽ thực thi các lệnh trong vòng lặp. Vòng lặp while kiểm tra biểu thức trước khi thực thi các dòng lệnh. Dưới đây là 1 ví dụ về việc sử dụng vòng lặp while trong stored procedure:

Mã:
 DELIMITER $$
DROP PROCEDURE IF EXISTS WhileLoopProc$$
CREATE PROCEDURE WhileLoopProc()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
WHILE x <= 5 DO SET str = CONCAT(str,x,','); SET x = x + 1; END WHILE; SELECT str; END$$ DELIMITER ;
Stored procedures trên tạo 1 chuỗi thông qua biến x cho đến khi x lớn hơn 5 và sau đó in chuỗi này ra màng hình bằng phát biểu select. 1 trong những lỗi mà lập trình viên hay mắc phải là biến x được dùng mà chưa được khởi tạo, giá trị của x lúc đó là NULL, vì vậy điều kiện lặp luôn luôn đúng, kết quả là đoạn mã bên trong vòng lặp while thực thi liên tục cho đến khi database của bạn bị crashed.

Vòng lặp repeat

Cú pháp của vòng lặp repeat:

Mã:
REPEAT
Statements;
UNTIL expression
END REPEAT
Dòng lệnh đầu tiên được thực thi, sau đó chương trình mới kiểm tra tới biểu thức logic. Nếu biểu thức logic có giá trị true, các dòng lệnh bên trong sẽ được lập lại liên tục cho đến khi biểu thức logic có giá trị false. Vì vòng lặp repeat kiểm tra biểu thức logic sau khi đã thực thi 1 lần dòng lệnh nên repeat được biết như vòng lặp tiền kiểm tra (post-test loop). Chúng ta có thể viết lại stored procedure trên bằng vòng lặp repeat như sau:

Mã:
 DELIMITER $$
DROP PROCEDURE IF EXISTS RepeatLoopProc$$
CREATE PROCEDURE RepeatLoopProc()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
REPEAT
SET str = CONCAT(str,x,',');
SET x = x + 1;
UNTIL x > 5
END REPEAT;
SELECT str;
END$$
DELIMITER ;
Chú ký không có delimiter (;) sau phát biểu UNTIL

Vòng lặp loop, leave và iterate

Phát biểu leave cho phép bạn rời vòng lặp. Nó gần giống với phát biểu break trong các ngôn ngữ khác như Java, C#...
Phát biểu Iterate cho phép bạn bắt đầu vòng lặp trở lại. Nó gần giống như phát biểu continue trong Java hay C#.
MySql cũng hỗ trợ vòng lặp loop cho phép bạn thực thi dòng lệnh lặp 1 cách cơ động. Một ví dụ về vòng lặp loop

Mã:
 DELIMITER $$
DROP PROCEDURE IF EXISTS LOOPLoopProc$$
CREATE PROCEDURE LOOPLoopProc()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
loop_label: LOOP
IF x > 10 THEN
LEAVE loop_label;
END IF;
SET x = x + 1;
IF (x mod 2) THEN
ITERATE loop_label;
ELSE
SET str = CONCAT(str,x,',');
END IF;

END LOOP;
SELECT str;
END$$
Store procedure trên tạo dựng 1 chuỗi với các số chẵn. Đầu tiên, ta định nghĩa một nhãn loop, nếu biến x lớn hơn 10 thì vòng lặp kết thúc thông qua phát biểu leave. Nếu x lẻ, iterate sẽ bỏ qua các dòng lệnh bên dưới nó và tiếp tục vòng lặp mới, ngược lại, block code trong phát biểu else sẽ thực thi để tạo chuỗi với các số chẵn.
___________

9:59 PM - No comments

Giới thiệu về stored procedure trong MySQL (P.5)

Các mệnh đề điều kiện trong Stored Procedures

Mệnh đề điều kiện cho phép bạn thực thi các đoạn mã (code) dựa trên giá trị của một hoặc nhiều biểu thức logic kết hợp. MySQL hỗ trợ 2 mệnh đề điều kiện là IF và CASE.

Mệnh đề IF

Cú pháp của mệnh đề IF:

Mã:
IF expression THEN commands
[ELSEIF expression THEN commands]
[ELSE commands]
END IF;
Các lệnh nằm trong khối IF, ELSEIF hoặc ELSE chỉ được thực thi khi mệnh đề có chân trị là TRUE. Một trong những cái "bẫy" hay mắc phải là biểu thức của mệnh đề IF có giá trị NULL, khi 1 biểu thức logic có giá trị NULL, nó không được xem là TRUE hay FALSE. Dưới đây là 1 số ví dụ của mệnh đề IF:

Mã:
IF expression THEN commands
END IF;
IF expression THEN commands
ELSE commands
END IF;
IF expression THEN commands
ELSEIF expression THEN commands
ELSE commands
END IF;
Bạn có thể thấy các mệnh đề IF có thể lồng vào nhau.

Mệnh đề CASE

Khi có nhiều biểu thức logic được sử dụng với mệnh đề IF, mã chương trình của bạn sẽ rất khó đọc. Trong tình huống này, bạn có thể sử dụng mệnh đề CASE để làm cho chương trình trông sáng sủa hơn.

Cú pháp của mệnh đề CASE:

Mã:
CASE
WHEN expression THEN commands

WHEN expression THEN commands
ELSE commands
END CASE;
__________________

9:58 PM - No comments

Giới thiệu về stored procedure trong MySQL (P.4)

Parameters trong Stored Procedures

Trong phần này, bạn sẽ học cách viết 1 stored procedures với parameter. Tôi cũng sẽ cung cấp cho bạn 1 vài ví dụ về stored procedure, qua đó giúp bạn hiểu sâu hơn về parameter trong stored procudes.

Hầu hết các stored procedures đều có param. Param làm cho stored procedure trở nên linh động và hữu dụng hơn. Trong MySQL, 1 param thuộc 1 trong 3 mode sau: IN, OUT và INOUT.
IN: bất cứ sự thay đổi giá trị nào lên param này bên trong stored procedure đều không có kết quả. Nghĩa là param vẫn giữ nguyên giá trị của nó sau khi ra khỏi stored procedure. Ví dụ, bạn truyền vào stored procedure GetAll 1 param có tên Id với giá trị là 10. Ngay cả khi trong stored procedure GetAll, bạn có cố tình thay đổi giá trị của param Id thì giá trị của nó sau khi thực thi stored procedure vẫn là 10.
OUT: cho phép stored procedure thay đổi giá trị của param và trả nó về chương trình gọi.
INOUT: kết hợp giữa 2 mode trên. Bạn có thể truyền 1 param dạng này vào stored procedure và nhận lại 1 giá trị mới.
Cú pháp để khai báo param trong stored procedure:

Mã:
MODE param_name param_type(param_size)
MODE có thể là IN, OUT hay INOUT tùy thuộc vào mục đích sử dụng của bạn.
Param_name là tên của param. Tên của param không nên trùng với tên của column hay table và phải tuân theo quy tắt đặt tên cho param. Theo sau tên param là kiểu param và kích cỡ của nó.

Mỗi param được ngăn cách bởi dấu “,” nếu stored procedure có nhiều hơn 1 param.
Trong ví dụ này, stored procedure có nhiệm vụ lấy các thông tin của tất cả các office ở 1 country nào đó.

Mã:
DELIMITER //
CREATE PROCEDURE GetOfficeByCountry(IN countryName VARCHAR(255))
BEGIN
SELECT city, phone
FROM offices
WHERE country = countryName;
END //
DELIMITER ;
Bạn có thể thấy, countryName được dùng như 1 param kiểu IN. Kiểu dữ liệu của countryName là varchar và kích thước là 255. Trong phần thân của stored procedure, ta nhận được thông tin của tất cả các office trong country được xác định bởi param countryName.

Giả sử bạn muốn nhận được thông tin về các office ở USA, bạn gọi stored procedure như sau:

Mã:
CALL GetOfficeByCountry('USA')
Tương tự, nếu muốn lấy thông tin của tất cả các văn phòng nằm ở France, gán giá trị của countryName=”France”

Mã:
CALL GetOfficeByCountry(‘France’)
Ví dụ thứ 2, ta sẽ viết 1 stored procedure để tính số lượng các order theo theo từng loại order riêng biệt được xác định bằng chính trạng thái của order đó, ví dụ : shipped, resolverd, cancelled, on hold, disputed hay in process

Mã:
 DELIMITER $$
CREATE PROCEDURE CountOrderByStatus(
IN orderStatus VARCHAR(25),
OUT total INT)
BEGIN
SELECT count(orderNumber)
INTO total
FROM orders
WHERE status = orderStatus;
END$$
DELIMITER ;
Stored procedure CountOrderByStatus có 2 param:
orderStatus param có kiểu IN,.
Total param có kiểu OUT.
Để lấy số lượng order theo trạng thái shipped, ta sử dụng phát biểu:

Mã:
CALL  CountOrderByStatus('Shipped',@total);
SELECT @total AS total_shipped;
Lấy số lượng order ở trạng thái “in process”:

Mã:
CALL CountOrderByStatus('in  process',@total);
SELECT @total AS total_in_process;
Store procedure thứ 3 dùng để minh họa cho trường hợp param là INOUT. Store procedure này có chức năng in hoa (capitalize) các ký tự đầu tiên của 1 từ trong chuỗi, sau đó trả về cho chương trình gọi thông qua chính param vừa được truyền vào:

Mã:
 DELIMITER $$
CREATE PROCEDURE `Capitalize`(INOUT str VARCHAR(1024))
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE myc, pc CHAR(1);
DECLARE outstr VARCHAR(1000) DEFAULT str;
WHILE i <= CHAR_LENGTH(str) DO SET myc = SUBSTRING(str, i, 1); SET pc = CASE WHEN i = 1 THEN ' ' ELSE SUBSTRING(str, i - 1, 1) END; IF pc IN (' ', '&', '''', '_', '?', ';', ':', '!', ',', '-', '/', '(', '.') THEN SET outstr = INSERT(outstr, i, 1, UPPER(myc)); END IF; SET i = i + 1; END WHILE; SET str = outstr; END$$ DELIMITER ;
Cách gọi capitalize trong stored procedure:

Mã:
SET @str = 'mysql stored procedure tutorial';
CALL Capitalize(@str);
SELECT @str;
Chuỗi trả về thông qua @str: ‘Mysql Stored Procedure Tutorial’

9:56 PM - No comments

Giới thiệu về stored procedure trong MySQL (P.3)

Biến trong stored procedure

Khai báo biến

Biến trong stored procedure được sử dụng để lưu trữ kết quả tức thời. Cú pháp khai báo biến:

Mã:
DECLARE variable_name datatype(size) DEFAULT default_value;
Như bạn thấy, ngay sau từ khóa DECLARE là tên biến. Bạn nên tuân theo qui ước đặt tên biến. Tên biến không nên trùng với tên của table hay colume trong database.

Tiếp theo là xác định kiểu dữ liệu của biến, đó là 1 trong những kiểu dữ liệu mà MySQL hỗ trợ sẵn: Int, varchar, datetime...Kế đến là kích cỡ của biến. Khi bạn khai báo 1 biến, nó được tự động khởi tạo giá trị mặc định là null. Bạn có thể thay đổi giá trị mặc định cho biến bằng cách sử dụng phát biểu DEFAULT. Ví dụ, cú pháp khởi tạo 1 biến có tên total_sale với kiểu dữ liệu là int, giá trị mặc định là 0 như sau:

Mã:
DECLARE total_sale INT DEFAULT 0
Có thể dùng 1 từ khóa DECLARE để khai báo 2 hay nhiều biến có cùng kiểu dữ liệu:

Mã:
DECLARE x, y INT DEFAULT 0
2 biến x và y với cùng kiểu dữ liệu int, giá trị mặc định (của cả 2) là 0.

Gán giá trị cho 1 biến

Sau khi khai báo biến, bạn có thể sử dụng chúng. Để gán 1 giá trị cho 1 biến, bạn dung phát biểu SET như sau:

Mã:
 DECLARE total_count INT DEFAULT 0
SET total_count = 10;
Biến total_count lúc này có giá trị là 10.
Ngoài cách dùng phát biểu SET, chúng ta cũng có thể sử dụng SELECT … INTO để gán kết quả của 1 truy vấn cho 1 biến:

Mã:
 DECLARE total_products INT DEFAULT 0
SELECT COUNT(*) INTO total_products
FROM products
Ở ví dụ trên, chúng ta khai báo 1 biến total_product và khởi tạo giá trị ban đầu bằng 0, sau đó sử dụng phát biểu SELECT … INTO để gán giá trị cho biến total_products bằng tổng số sản phầm (products) trong bảng products.

Phạm vi của 1 biến

Mỗi một biến có phạm vi hoạt động của nó. Nếu bạn khai báo biến bên trong 1 stored procedure, biến đó sẽ còn hiệu lực cho đến khi nào gặp từ khóa END của stored procedure. Nếu bạn khai báo biến bên trong block BEGIN/END của stored procedure, biến sẽ hết hiệu lực khi gặp từ khóa END của block BEGIN/END này.

Bạn có thế khai báo 2 hay nhiều biến cùng tên trong các phạm vi (scope) khác nhau, các biến này sẽ có hiệu lực trong phạm vi riêng của chúng. Dĩ nhiên điều này được khuyến cáo là không nên làm.

Một biến với ký tự “@” làm tiền tố được xem là biến thuộc phạm vi session. Nó sẽ tồn tại dến khi nào session còn tồn tại.

4:54 AM - 6 comments

Giới thiệu về stored procedure trong MySQL (P. 2)

Trong phần này, bạn sẽ được hướng dẫn cách viết 1 stored procedure đơn giản và cách thức triệu gọi stored procedure này từ MySQL command line.

Viết stored procedure đầu tiên

Stored procedure đầu tiên khá đơn giản. Nó chỉ có chức năng duy nhất là lấy thông tin về tất cả các sản phẩm được lưu trong bảng products. Hãy xem xét đoạn mã dưới đây:

Mã:
 DELIMITER //
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END //
DELIMITER ;
Dòng đầu tiên bạn thấy là DELIMITER//. Dòng lệnh này thực sự không liện quan đến stored procedure. Phát biểu DELIMITER được dùng để thay đổi cú pháp phân cách chuẩn từ dấu “;” thành một dấu khác, trong trường hợp này là dấu “//”. Với việc làm này, bạn có thể viết được nhiều dòng SQL trong 1 stored procedure bằng việc sử dụng dấu “;” làm dấu phân cách dòng.

Sau từ khóa END, bạn lại sử dụng dấu phân cách // để ra hiệu cho trình biên dịch biết là đã hết stored procedure. Dòng cuối cùng, đưa cú pháp phân cách trở về trạng thái “nguyên thủy”, tức dấu “;”.

Để tạo 1 stored procedure mới, bạn sử dụng phát biểu CREATE PROCEDURE. Sau phát biểu CREATE PROCEDURE là tên của stored procedure mà bạn muốn đặt, trong ví dụ trên là GetAllProducts. Dĩ nhiên, tên của stored procedure ít nhiều mang tính gợi nhớ.

Phần thân của stored procedure được bắt đầu bởi cặp từ khóa BEGIN và END. Các câu lệnh SQL được đặt trong block này. Chúng ta sẽ phân tích chi tiết trong các phần sau. Đến đây, bạn đã hoàn tất việc tạo 1 stored procedure. Tiếp theo, chúng ta cần biết cách thức để triệu gọi 1 stored procedure trong 1 ứng dụng hay trong command line của MySQL.

Triệu gọi stored procedure

Để triệu gọi 1 stored procedure, chúng ta sử dụng câu lệnh SQL sau:

Mã:
CALL STORED_PROCEDURE_NAME()
Ví dụ với stored procedure vừa tạo ở trên:
Mã:
CALL GetAllProducts();
Bạn sẽ lấy được thông tin về tất cả các sản phẩm trong bảng products.

Sơ luận

Trong phần này, bạn đã được giới thiệu về cách thức thay đổi dấu phân cách chuẩn bằng việc sử dụng phát biểu DELIMITER. Việc làm này cho phép bạn có thể gõ nhiều dòng lệnh SQL bên trong 1 stored procedure. Bạn cũng được học cách viết 1 stored procedure đơn giản thông qua việc sử dụng phát biểu CREATE PROCEDURE và sau đó, triệu gọi từ command line với phát biểu CALL.

4:47 AM - 1 comment

Giới thiệu về stored procedure trong MySQL (P.1)

Định nghĩa stored procedure

Stored procedure được định nghĩa như một tập các khai báo sql được lưu trữ ngay trong cơ sở dữ liệu (database) và sau đó, được triệu gọi bởi một program, một trigger hay thậm chí là một stored procedure khác.

Một stored procudure, như chính định nghĩa của nó, có tính đệ qui. Hầu hết các RDMBS (Relational database management system - hệ quản trị cơ sở dữ liệu quan hệ) đều hỗ trợ stored procedure đệ qui, tuy nhiên MySql lại không hỗ trợ tốt tính năng này. Vì vậy, chú ý kiểm tra phiên bản của MySql trước khi bạn có ý định dùng stored procedure theo kiểu đệ qui.

Stored procedure trong MySQL

Hiện tại, MySql là 1 RMBSM mã nguồn mở (open source) được sử dụng rộng rãi trong cộng đồng phát triển cũng như cho mục đích thương mại. Tuy nhiên, từ “thuở sơ khai”, MySql không hỗ trợ stored procedure, trigger hay event…Từ phiên bản 5.0 trở lện, những chức năng này mới được thêm vào MySql data base engine với mục đích đem lại tính linh động và mạnh mẽ hơn cho MySQL.

Nếu hứng thú với loạt bài về stored procedure này, bạn nên cài MySQL phiên bản 5.x trên máy tính

Những ưu điểm của stored procudure

Stored procedure làm tăng khả năng thực thi của ứng dụng. Sau khi được tạo, stored procedure sẽ được biên dịch (compile) và lưu trữ ngay trong database. Lẽ dĩ nhiên, nó sẽ chạy nhanh hơn là một lệnh sql chưa compile được gởi trực tiếp từ ứng dụng.

Stored procedure làm giảm lưu lượng thông tin giao tiếp giữa ứng dụng và database server, thay vì gởi những câu lệnh sql chưa complile dài lằng ngoằn, ứng dụng chỉ việc gởi tên của stored procedure và lấy lại kết quả

Stored procedure có thể được tái sử dụng và chuyển sang bất cứ ứng dụng nào muốn sử dụng chúng. Stored procedure có thể “trưng ra” giao diện database cho tất cả các ứng dụng, vì vậy lập trình viên không cần viết lại các chức năng đã hỗ trợ sẵn trong stored procedure trong tất cả các chương trình.

Stored procedure cũng rất an toàn. Quản trị viên cơ sở dữ liệu có thể gán quyền cho ứng dụng truy xuất vào các stored procedures được chỉ định mà không cho phép truy cập đến các bảng (table) ở phía dưới.
Bên cạch những tiện lợi như trên, stored procedure vẫn có 1 số bất tiện dưới đây:

Những nhược điểm của stored procudure

Stored procedure làm cho database server phải tốn nhiều tài nguyên về cả bộ nhớ lẫn xử lý. Thay vì tập trung vào tính năng lưu trữ và nhận dữ liệu, bạn còn phải yêu cầu database server thực hiện 1 loạt các tính toán logic hay các thao tác xử lý phức tạp vốn không thuộc “sở trường” của database server.

Stored procedure chỉ chứa đựng các khai báo sql, vì vậy rất khó có thể viết 1 procedure nhằm thực hiện các thao tác xử lý phức tạp như các ngôn ngữ khác làm được ở tần ứng dụng như C#, Java, C++…

Bạn cũng không thể debug stored procedure trong hầu hết các RDMBS và trong cả MySQL. Có 1 vài cách để khắc phục nhược điểm này, tuy nhiên vẫn chưa hoàn hảo lắm.

Việc viết và bảo trì (maintain) stored procedure thường yêu cầu 1 loạt các kỹ năng chuyên biệt nhiều khi không phải là kỹ năng của lập trình viên. Điều này dẫn đến các vấn đề trong cả khía cạnh phát triển ứng dụng và bảo trì sản phẩm.

Sơ luận

Stored procedure có những thuận tiện cũng như bất lợi như đã đề cập ở trên. Khi phát triển ứng dụng, bạn nên đánh giá giữa những ưu và nhược điểm để quyết định có nên sử dụng stored procude hay không. Các tutorial tiếp theo sẽ hướng dẫn bạn cách sử dụng store procedure trong lập trình database với 1 vài ví dụ thực tế.

4:17 AM - No comments

Javascript confirm box with yes/no option

This's a nice, brilliant piece of code from http://www.delphifaq.com.
It makes a yes/no option confirm instead of ok/cancel. Work fine in IE.
<script language=javascript>
/*@cc_on @*/
/*@if (@_win32 && @_jscript_version>=5)

function window.confirm(str)
{
execScript('n = msgbox("'+str+'","4132","my title")', "vbscript");
return(n == 6);
}
@end @*/
var r = confirm("Can you do it?");
alert(r);
</script>