男人一生所追求的幸福

  2008/8/18 AM 11:25,這個六、日公司有點事,所以都在加班,我已經超過30幾個小時沒闔眼,對我這個老人家,體力實在有點吃不消,但還是要跟各位談談這位讓我鐘愛一生的人。

  其實昨晚她是被我趕回家的,她想我陪也想陪我,因為她有身孕不能太勞累,而且今天她還要上班,要早點上床休息。其實我回到家她已經在上班了,但當我回到家時才知道,我這小可愛還準備了一份禮物給我…害我又無法入眠!

Sherry的信書  男人一生所追求不就是這簡單的幸福嗎!

  老婆,Me too。

踢爆--建設公司的黑心廣告

  這年頭流行「踢爆」,我本身是不喜歡那些影響人家私生活的踢爆,不過如果是揭發「黑心」、「不良」、「壞人壞事」…我本身到是不反對。不知什麼時候開始,心裡開始有一點正義感,想對社會進一點心力,希望能對反應一些不合理的事,這就是我想在Blog反應的事。

  以下的事是發生在我上班必經之路上,本來這事是不會引起我注意的,只是我有隻心愛的狗狗,我和婆婆每天都會帶到牠到處走走,有一天走著走著發現了這樣的黑心事件。

  地點:新竹市水源街、新竹市公道五路

  在新竹市水源街與公道五路有一家愛賣(主角不是愛賣),這裡算是一個車水馬龍的地段,而就在幾週前的一天,我到這裡散步時發現有幾台應該是報廢的小貨車,因為玻璃都已經破碎、座位都已經損壞,但上面的廣告還是新的。但引起我注意的是它被張貼了好幾張黃色公告單,而且它是停放在付費停車格之內。一台沒有車牌的車停在付費停車格之內,想也知道,停車格的開單員當然拿它沒辨法!

  但時間一天一天過去,我發現,這些車不止一台,是有許多台,而且這些車上的廣告都是同一家建設公司的廣告文案,而且今天我又發現,那些黃色公告單有人會去把它「撕」下來…我不知道用意為何?

  用這樣的方式在打廣告,遊走在法律邊緣的方法,實在是我所不認同的,以下是今天2008/8/17早上我帶狗狗去散步所照的照片,就我個人而言,這家建設公司的任何建案我將永遠不會考慮,因為他們這樣做生意的心態…有問題。有問題的建設公司蓋出來的房子…會不會有問題?

  水源街:

  

  公道五路:




  踢爆還是交給專家,以上資訊我會轉寄給Apple咬一口,希望能有個好結果。

  台灣蘋果日報總部
  爆料投訴
  電話專線:0809-012-555 傳真專線:0809-013-666 電子郵件:news@appledaily.com.tw

  台灣壹週刊
  爆料投訴
  投訴專線:(02)6601-9119 傳真:(02)6601-9042 爆料投訴信箱:119@nextmedia.com.tw

無廢話SQL語法--1. 環境準備

前言

  不管你是使用什麼類型的資料庫軟體,MySQL、SQL Server、DB2、Oracel、Sybase、Teradata、PostgreSQL…基本上它都只是一個在後端Standby(待命的)的資料庫軟體,它會在那裡癡癡的等著你,你必須與他溝通,不論你的前端是使用什麼程式語言,VB、C、C++、C#、Ruby、Java、PHP、JSP、Javascript…,只要是需要與資料庫來做存取,都必須使用資料庫的共通語言來和它溝通,那它才會幫你做事,成為你的好幫手,而這個資料庫的共通語言就是:SQL語法。目前SQL語法的國際標準為:SQL/99,除了一些各家資料庫軟體特別的語法、函數外,基本上所有的資料庫軟體都支援SQL語法,所以你想進入資料庫的世界,那SQL語法就是基本功夫,就是你的內功,你的根基。

  以我為例子,我在開發*.aspx的網站時的關係圖如下:

前端(ASP.NET) <--> SQL語法 <--> 後端(RDBMS)

  我們的例子將會在SQL Server 2005 Express中進行,如果你的電腦中沒有這些套件,請先下載 1. Microsoft .NET Framework 2.0、2. Microsoft .NET Framework 2.0語言套件、3. SQL Server 2005 Express、4. Microsoft SQL Server Management Studio Express,下載後請依順序安裝到電腦中,這些軟體及工具都是免費的。(註:SQL Server 2005 Express簡稱:SSE;Microsoft SQL Server Management Studio Express,簡稱:SSMSE。)
  • SQL Server 2005 Express最低要求是.NET Framework 2.0,目前.NET Framework在2008年8月已經更新到.NET Framework 3.5 Service Pack 1,因為我們這裡不是要寫.NET Framework程式,我們只是要架設一個測試環境,專注在SQL語法,所以只需要安裝2.0即可。
  • 你也可以直接下載.NET Framework 3.5 Service Pack 1來安裝,它會把所有2.0、3.0、3.5環境架設起來,不會有任何影響。
  環境準備好了,你還必須再下載一個範例資料庫,Northwind(北風資料庫),SSE資料庫不包含範例資料庫,下載後安裝時會直接把範例資料庫安裝到「C:\SQL Server 2000 Sample Databases」目錄,我們所有的例子都會以這個資料庫中的資料為例子來實作。

  如果你已經安裝好所有軟體及工具,那我們就來做第一件事,匯入Northwind資料庫及pubs資料庫到SSE。步驟相當的簡單:
  1. 進入「C:\SQL Server 2000 Sample Databases」目錄
  2. 點擊「instnwnd.sql」檔案,進入SSMSE畫面,按下「執行」或「F5」。
  3. 點擊「instpubs.sql」檔案,進入SSMSE畫面,按下「執行」或「F5」。
  4. 匯入完成後,就可以進入「新增/移除程式」將「Microsoft SQL Server 2000 Sample Databases Scripts」移除。
  這樣就準備好了我們所有的實作環境,簡單吧,下一篇我們先簡介SSE的管理工具:SSMSE,再進入SQL語法。
註:RDBMS:Relational database management system,關連式資料庫管理系統。


#2008/8/17:更新至.NET Framework 3.5 Service Pack 1環境。

Bandwidthd:簡單、好用又強大,各別IP流量統計

  你是否有過這樣的困擾或經驗,幸幸苦苦的架好了一個強大的MRTG,終於可以好好的看看網路流量的情況了,但是看到 的是 一個「總體」的流量。正當高興時,有人在你的網路中「嘿嘿嘿」或是下載P2P或是一個可憐又無知的小朋友電腦中毒了。這時,終於看到MRTG美麗的圖形, 上上下下,左左右右。但你就是找不出來,是「誰」?誰在創造這些美麗的圖形,是「誰」?是「誰」?

  終於,天邊出現一道光,人們跟著說:「就是那道光,Bandwidthd」。(小說看太多了@.@~)

   Bandwidthd 是一套以圖形化、網頁化的方式,顯示你的 TCP/IP 網段中的使用狀況。Bandwidthd 圖形化是以網段中「各自獨立的 IP」為對象,它可以不同的色彩來顯示 HTTP, TCP, UDP, ICMP, VPN 以及 P2P 協定的流量。可以讓網管人員更了解使用者使用網路的情況。和 MRTG 不同的是,bandwidthd 統計是各別的 IP 用量,而不像 MRTG 是顯示某一網路介面的總量,對於網管人員而言,Bandwidthd 可說是一項好用的利器。而且在官方網站上有提供這樣的一個數據:My entire ISP (2000-3000 IP addresses across 4 states) is graphed on a Celeron 450 every 10 minutes。意思是說,使用賽陽450的CPU,可以在10分鐘掃完2000-3000 IP。也就是說,我們可以拿比較舊的電腦來做這個統計工作,而不用擔心效能問題。並且,他也提供和資料庫整合的功能,實在是太棒。最最最重要的是,他的架 設,超簡單。等不及了,我們快來動手吧!
  • 實作系統:CentOS 4.5 Server, 核心版本:2.6.9-55.EL
  • 實作配備:PⅡ Celeron 450 + 256 RAM ( 剛好可以證明:「這是真的。」跟隨者:「真的~~~」 )
  目前最新版本為 2.0.1 (2007/5/23),而且他還有提供Windows版本,真的是太棒了。
  先以 root 登入:
  在安裝之前,我們先看看 README / INSTALL.Unix ,發現有些東西必須先確認一下,你必須確認有安裝以下函式庫:
  檢查一下:
  • rpm -qa | grep libpcap
      找出:libpcap-0.8.3-10.RHEL4
  • rpm -qa | grep libpng
      找出:libpng-1.2.7-3.el4
  • rpm -qa | grep libgd
  你會發現,最後一個 libgd 會是空白的,沒關係,這跟等一下的錯誤有關哦!如果沒有安裝的話,建議使用 yum 來安裝。
  • yum -y install libpcap*
  • yum -y install libpng*
  • yum -y install libgd* (不會安裝任何套件,裝孝為嗎?請往下看,大人。)
  建議把第二個 libpng 執行一下,因為我發現有另一個 libpng10 的套件,而且我未安裝 libpng10 套件時,會出現以下錯誤訊息:
  • configure: error: Bandwidthd requires but cannot libpng
很明顯的,它是使用 libpng10 而不是使用系統內建的 libpng,然後開始安裝吧:
  • ./configure && make install
不過在configure時一直出現以下的錯誤:
  • configure: error: Bandwidthd requires but cannot find libgd
  找又找不到(rpm),安裝也沒有東西(yum),是怎樣!!! (集氣完快成了{..ooOO}!) 到網站看看有沒有什麼資訊( 網站上說:The GD library has moved to http://www.libgd.org/ ), 發現套件名稱都是以 gd 為開頭,那試試 yum search gd,果然找到一堆套件,還好我試了第一次就OK了,不然可能要發功放氣一下才行了!(本來在另一台主機測試時,是直接使用 yum install gd* ,馬上就OK了,但想想有需要安裝那怎多東西嗎?所以就再找一台來試,結果在 CentOS4.4/4.5 情況都一樣,在非常Luck的情況下,試了第一個套件就成功,還好還好,汗~~~)
  • yum install gd-devel <-- 兇手就是他,看我的元氣彈!!!
  再重新configure一次
  • ./configure && make install
  成功了,沒有錯誤訊息了。 安裝完成後,它會將 bandwidthd 安裝至 /usr/local/bandwidthd 下,接下來就是 bandwidthd 超級簡單的設定,請編輯:
  • vi /usr/local/bandwidthd/etc/bandwidthd.conf
  在第 10, 11, 12 行,把這三行註解(#):
  • # subnet 10.0.0.0 255.0.0.0
  • # subnet 192.168.0.0/16
  • # subnet 172.16.0.0/12
   最後加上一行自己網域的設定:
  • subnet 192.168.1.0/24
 一個Intranet, Class C, 指定你要統計的subnet,全部的設定就只有一行,超簡單吧!存檔之後,便可準備執行。執行bandwidthd:
  • cd /usr/local/bandwidthd
  • ./bandwidthd
  然後我們只要在 web 主目錄建立一個Link即可:
  • cd /var/www/html
  • ln -s /usr/local/bandwidthd/htdocs bw ( 目錄名稱自己決定 )
  接著您需要等個幾分鐘,便可用 http://IP/bw or http://domain/bw 看到網路中各主機的頻寬使用情況!
注意一
再來因為這個程式是使用 C 語言所寫,所以你的系統必須要有 gcc 和相關的套件,如果你在 configure 時會出現:
  make: cc: Command not found
  或是
  configure: error: no acceptable cc found in $PATH
那怎請先把 gcc 安裝起來。我的 CentOS4.4 剛裝完時,還真的沒有 gcc ,產生了第二個錯誤訊息:
  yum -y install gcc*
或是把 gcc 升級到最新版本:
  yum -y update gcc*
應該就可以解決 configure 時的問題了。

注意二
以下是 bandwidthd 的 README 中倒數第二段,有一段話:

By default, Bandwidthd now runs in promiscuous mode. This means it can be used to monitor traffic not routing through it's host. Just make sure that the host and the actual router are on the same hub (Not switch) and everything will be ok.
注意那個粗體字,所以,請把 Bandwidthd 的主機與你的骨幹用hub連接,應該就會有所有的流量了。或者,如果你的nat或router是自己架的Linux,那就直接裝在 nat / router 主機上也行。
Windows 安裝 Bandwidthd
  Bandwidthd 在 Windows 的安裝,更簡單100倍。我們快來看看!
  1. 先把檔案下載回來:http://nchc.dl.sourceforge.net/sourceforge/bandwidthd/bandwidthd-2.0.1-binary-windows.zip
  2. 解 壓縮後,會產生一個 bandwidthd 的目錄,移到你要放 program 的地方(一般是放到 \program file\ 之下)。然後先看一下 README.txt 和 INSTALL.Windows.txt 有一件事要確認,你是否有安裝 Winpcap 這個軟體,如果沒有的話,請先下載:http://www.winpcap.org/ ,最新版是 winpcap 4.0。
  3. 然後,修改 bandwidthd/etc/bandwidthd.conf ,將你要統計的 subnet 設定上去,存檔。
  4. 點擊 "Install Service.bat" 這支程式,把 bandwidthd 安裝到 Windows系統服務中。
  5. 「開始」--> 「我的電腦」 --> 滑鼠按右鍵 --> 「管理」 --> 「服務及應用程式」 --> 「服務」 --> 「 bandwidthd 」
  如果要停止 bandwidthd.exe 必須使用 「 Windows 工作管理員 」來直接停用四個 bandwidthd.exe。另外要注意,是否有 cygrunsrv.exe 這支程式,有的話一併Kill。 如果要把 bandwidthd 從「服務」中移除,請先把所有 bandwidthd 工作停止,然後點擊 "UnInstall Service.bat" 這支程式就可以了。
  要看統計的結果,進入 bandwidthd\htdocs 點擊 index.html 就可以看到美美統計圖形了。可以開始抓……山豬了。

本文PDF下載:



註:本文寫於2007/7/25

無廢話SQL語法--4.第一大將SELECT(2)

SELECT基礎語法

  請直接進入SSMSE管理工具的Northwind的SQLQuery查詢。然後將實例中的語法使用「複製/貼上」的方法,然後在工具中按「F5」執行,看其結果。以下為簡省畫面,除特別結果,不再截圖,請自行測試。

  複習:

  SELECT 欄位名稱
  FROM 資料表名稱
  WHERE 條件

  實例一:取得Products資料表中所有產品的明細資料

  SELECT *
  FROM Products

  在欄位方面我們使用星號「*」時,代表我要取出FROM資料表中所有的欄位,不過在實際進行程式設計時很少用到這個方式,因為這個方法會對程式效率產生影響,所以建議盡量能指定明確且你所需要的欄位名稱。這個SELECT語法中沒有使用到WHERE條件,沒有條件就是代表「我要取出全部資料」。

  實例二:從Products資料表取出ProductName(產品名稱)及UnitPrice(單價)

  SELECT ProductName,UnitPrice
  FROM Products

  指定明確欄位名稱。

  實例三:從Products資料表取出ProductID,ProductName,UnitsOnOrder,UnitsInStock,UnitPrice(欄位順序要一樣)

  SELECT ProductID,ProductName,UnitsOnOrder,UnitsInStock,UnitPrice
  FROM Products

  取出欄位的顯示安排是可以依照你的規劃來設計,而寫出明確欄位名稱及順序的好處是可以增加語法的可讀性,你可以知道取出了什麼資料,另外可以排除一些不必要錯誤,例如,如果你在欄位名稱使用「*」,但如果有人變更了資料表的欄位結構,你將很難查出錯誤。原則就是:你需要什麼那就取出什麼。

  實例四:從Products資料表取出商品單價(UnitPrice)大於50元的ProductName,UnitPrice

  SELECT ProductName,UnitPrice
  FROM Products
  WHERE UnitPrice > 50

  WHERE是一種「過濾」的動作,絕大部份的情況下,我們很少要取出資料表中全部的資料,而是要資料表中「特定」的資料,而WHERE就是在幫我們過濾不必要的資料,找出我們需要的資料。WHERE後的條件可以使用數值的比較運算子,常用的運算子有:> 大於、< 小於、>= 大於等於、<= 小於等於、= 等於、<>、!= 不等於(SQL Server支援這兩種不等於的語法),還可以使用邏輯運算子來結合多個條件(AND、OR),例如將上述的WHERE修改為:「WHERE (UnitPrice > 50) AND (UnitPrice <> 50) OR (UnitsInStock > 50)

  實例六:從Employees資料表取出City(城市)是在London(倫敦)同事的FirstName

  SELECT FirstName
  FROM Employees
  WHERE City = 'London'

  這個實例要說明的是當比較的資料型態為「字串」時,字串必須使用「'」到「'」單引號符號之間,而不是我們常在撰寫程式時使用的「"」雙引號符號,請小心注意,你可以移除「'」或是換上「"」測試看看。而這個「'」也就是SQL語法常被SQL Injection攻擊的起點,所以如果在撰寫動態網頁程式時,一定要非常小心處理這個「'」,有關「SQL Injection攻擊」我們有機會再聊聊。

  實例七:從Products資料表取出產品名稱中有含有「Anton」的ProductName,UnitPrice

  SELECT ProductName,UnitPrice
  FROM Products
  WHERE ProductName LIKE '%Anton%'

  LIKE是一種「模糊搜尋」,它必須使用如百分號(%)或底線(_)合作使用。%代表0個或以上的任意字元。_則是只能有1個字元。另外注意,LIKE在搜尋是不會分字母大小寫,當然中文不會有大小寫的問題。所以'%Anton%'表示Anton之前與之後有任意幾個字元都符合條件。例如:

  LIKE 'ANTON%' :以ANTON開頭的字串將符合條件。
  LIKE '%anton%'  :含有anton字串將符合條件。
  LIKE '%Anton'  :以Anton結束的字串將符合條件。
  LIKE 'C___'  :(C後面是三個底線)表示以C開頭且只含三個字元將符合條件。

  如果你只知道要找一個'kkbruce'字串,但不知道在那一個欄位,尤其是在程式設計時常會進行多個欄位的模糊搜尋,只要使用OR來連接LIKE條件即可,例如:Field1 LIKE '%kkbruce%' OR Field2 LILE '%kkbruce%' OR Field3 LIKE '%kkbruce%' …,將資料表中所有的資料欄位全部用OR起來,那就可以查詢全部欄位。

  LIKE在資料查詢的條件設定時是很重要的使用方式,我們在深入一點點。想想,如果我們要查詢百分比'%'符號時,那要如何下這個LIKE語法?LIKE '%%%'嗎?如果我們要查詢底線'_'時,是下LIKE '%_%'嗎?

  如果單從「字面上」來看,這樣寫法是沒有錯,但SQL Server會將「%」解釋為「0個或以上的任意字元」,「_」底線解釋為「只能有1個字元」,這不是我們要的結果。這時我們就要借助ESCAPE關鍵字的幫助,ESCAPE原意是「逃脫」,也可是我們可以指定一個「跳脫」的符號,當我們在LIKE使用中使用跳脫符號時,跳脫符號後的符號將以原意來解釋。我們用實例來說明:

  LIKE '%\%%' ESCAPE '\'
  LIKE '%\_%' ESCAPE '\'

  先指定'\'為跳脫符號,然後在LIKE中使用\%來代示\後面的%要使用原意(百分比)來解釋,第二個一樣,將\後面的_使用底線來解釋,這樣了解嗎。

  SQL Server中LIKE會使用到的萬用符號:

  %:任何含有零或多個字元的字串。
  _:任何單一字元。
  []:在指定範圍 ([a-f]) 或集合 ([abcdef]) 中的任何單一字元。
  [^]:不在指定範圍 ([^a-f]) 或集合 ([^abcdef]) 中的任何單一字元。

  最後在介紹一個SQL Server的CHARINDEX()的函數,它的語法是:

  CHARINDEX('要尋找之字元', [欄位名稱] )

  如果CHARINDEX找到你要的字元,會傳回一個大於零的值,沒有就傳回值零,所以上面的例子也可以改寫成:「WHERE CHARINDEX('%', ProductName) > 0」,一樣,可以使用OR來連接多個欄位的查詢,而且CHARINDEX()效率比LIKE還好,LIKE很重要,請好好了解。還有不了解,請查詢SQL Server線上叢書。
  
註:CHARINDEX()會傳回字串在資料欄位中的位置,所以當欄位內容有資料時,傳回的值就會大於零。
註:CHARINDEX()不屬於SQL語法,是SQL Server的函數。

  實例八:從Orders資料表取出1996年8月份(OrderDate )的訂單資料

  SELECT *
  FROM Orders
  WHERE OrderDate >= '1996/8/1' AND OrderDate <= '1996/8/31'

  日期的比較運算和數值一樣,另外還有一種用法是使用「BETWEEN~AND~」,本例中的WHERE可以寫成:   WHERE OrderDate BETWEEN '1996/8/1' AND '1996/8/31'   不過資料庫軟體在執行時還是會自動轉換為>=、<=的運算方式。
(NOT)IN的使用方法

  實例九:從Products資料表取出CategoryID(類別編號)為1,2,3的ProductName

  SELECT ProductName
  FROM Products
  WHERE CategoryID IN (1,2,3)

  IN括弧內的值為「其中任一個值符合」即可,而IN也可以轉換成OR的運算式,例如:

  WHERE CategoryID =1 OR CategoryID =2 OR CategoryID =3

  那我們使用OR就好了,為什要使用IN呢?那是因為OR這種運算式你只能使用在「清楚、明確」知道「個數」的地方,如我知道要取出1,2,3時使用,但如果我根本不知道會取出多少個值,那就要使用IN了,這我們後面會交代。

  我們也可以令IN的條件相反,也就是除了1,2,3其他的資料我都要,那就可以使用「NOT IN」,那WHERE敘述如下:

  WHERE CategoryID NOT IN (1,2,3)

  而OR敘述:

  WHERE NOT (CategoryID =1 OR CategoryID =2 OR CategoryID =3)

  NOT就是將整個結果相反的意思,原本成立變不成立,不成立變成立,這樣了解嗎!

NULL的概念(IS使用)

  實例十:從Suppliers資料表取出沒有HomePage(網頁)的CompanyName(公司名稱),也就是HomePage內容為NULL的公司。

  SELECT CompanyName
  FROM Suppliers
  WHERE HomePage = NULL

  如果你已經執行了,嗯,怎麼會是錯誤的?在SQL當中NULL代表一種「未定」或「不明」的狀態,而你不能拿「未定、不明」的值來比較(=、<、>、…)運算,當然也不使用NULL = NULL的比較,因為「未定不會等於未定」,這時我們必須使用IS這個比較運算子:

  WHERE HomePage IS NULL

  也就是明確的跟WHERE說,我要的是(IS)NULL這個值。IS也可以使用NOT,來使整個結果相反:

  WHERE HomePage IS NOT NULL

  IS NOT(不是),就是請找出其他不是NULL的資料。

結合資料表(INNER JOIN)及別名(Alias)