上一篇文章「在WSH環境下存取Access資料庫」中,使用組合SQL語法的方式將資料寫進資料庫,但這樣的方式在資料欄位數量較多時,是種相當痛苦的處理方法。
這篇嘗試使用ADODB.RecordSet物件來跟資料庫打交道,雖然以前只用過Delphi程式語言設計資料庫軟體,好在ADODB物件的用法差異並不會太大,語法、結構也都很類似(就是開資料庫連線、建立資料集、最後記得關閉資料庫連線‧‧‧等等),參考網路上的一些資料後,就試著動手寫寫看。
改以ADODB物件寫入Access的完整程式碼如下:
<?xml version="1.0" standalone="yes" encoding="big5"?> <package> <job> <script src="JScript/adojavas.js" type="text/javascript" language="javascript" charset="utf-8"></script> <script type="text/javascript" language="javascript" charset="utf-8"> <![CDATA[ /** * * 取得資料。 * * @author ace * * @version 2010/11/11 v0.1 * * @param {String} astrStockCode 股票代碼。 * * @returns {String} 網頁資料。 * * @requires Microsoft.XMLHttp * */ function getHttp(astrStockCode) { var strReturn = new String(""); var strURL = new String("http://tw.stock.yahoo.com/q/q?s=" + astrStockCode); var objXMLHttp = new ActiveXObject("Microsoft.XMLHttp"); objXMLHttp.open("GET", strURL, false, ""); objXMLHttp.send(); // todo: 加入是否正確取得資料之判斷式。 var strReturn = new String(objXMLHttp.responseText); return strReturn; } /** * * 剖析html資料。 * * @author ace * * @version 2010/11/11 v0.1 * * @param {String} astrTrnDate 交易日期。 * @param {String} astrStockCode 股票代碼。 * * @returns {Array} 陣列資料。 * */ function parseHTML(astrTrnDate, astrStockCode, astrContent) { var objReturn = new Array(); /** * * 建立瀏覽器物件。 * * @author ace * * @version 2010/11/16 v0.1 * * @see <a href="http://us.generation-nt.com/answer/parsing-html-jscript-help-59686112.html">Parsing HTML with JScript</a> * @see <a href="http://www.eggheadcafe.com/software/aspnet/36239301/jquery.aspx">Jquery</a> * */ var htmlfile = new ActiveXObject("htmlfile"); var window = htmlfile.parentWindow; var navigator = window.navigator; var document = window.document; var location = document.location; window.ActiveXObject = {}; // todo:載入html檔案發生錯誤時,無法被JavaScript的catch語法攔截?! htmlfile.open(); htmlfile.write("<script type=\"text/javascript\">window.onerror = function () {};</script>"); htmlfile.write(astrContent); htmlfile.close(); var objTR = document.getElementsByTagName("tr"); for (var intIndex = 0; intIndex < objTR.length; intIndex++) { var objTD = objTR[intIndex].getElementsByTagName("td"); if (objTD.length == 12) { objReturn.push(astrTrnDate); objReturn.push(astrStockCode); objReturn.push(objTD[2].firstChild.innerHTML); // 成交金額多了<b>標籤,再往下一個結點取資料。 objReturn.push(objTD[3].innerHTML); objReturn.push(objTD[4].innerHTML); objReturn.push(objTD[6].innerHTML.replace(",", "")); objReturn.push(objTD[7].innerHTML); objReturn.push(objTD[8].innerHTML); objReturn.push(objTD[9].innerHTML); objReturn.push(objTD[10].innerHTML); break; } } return objReturn; } /** * * 寫入Access資料表。 * * @author ace * * @version 2010/11/30 v0.1 * * @param {String} astrTrnDate 交易日期。 * @param {String} astrStockCode 股票代碼。 * @param {Array} aobjData 資料陣列。 * * @return * * @description 2010/11/30 陣列資料內容: * aobjData[0]:交易日期。 * aobjData[1]:股票代碼。 * aobjData[7]:開盤價格。 * aobjData[8]:最高價格。 * aobjData[9]:最低價格。 * aobjData[2]:收盤價格。 * aobjData[5]:成交張數。 * @description 2010/12/26 改以RecordSet物件寫入資料。 * */ function insertAccess(astrTrnDate, astrStockCode, aobjData) { var objConn = WScript.CreateObject("ADODB.Connection"); var objRS = WScript.CreateObject("ADODB.RecordSet"); try { strDatabase = new String("Stock.mdb"); objConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strDatabase; objConn.Open(); var strSQL = "select * from stocks_day_trn_log where 1=1 and trn_date='" + aobjData[0] + "' and stock_code='" + aobjData[1] + "' "; objRS.Open(strSQL, objConn, adOpenStatic, adLockOptimistic, adCmdText); // 若查無資料則新增。 if (objRS.EOF == true) objRS.AddNew(); objRS("trn_date") = aobjData[0]; objRS("stock_code") = aobjData[1]; objRS("open_price") = aobjData[7]; objRS("high_price") = aobjData[8]; objRS("low_price") = aobjData[9]; objRS("close_price") = aobjData[2]; objRS("trn_qty") = aobjData[5]; objRS.Update(); } catch (e) { throw e; } finally { objRS.Close(); objConn.Close(); } } // Program Start Here try { var objToday = new Date(); // 以系統日期當作交易日期,理想作法應以網頁記載時間為準。 var strTrnDate = new String(""); strTrnDate = objToday.getFullYear().toString() + (objToday.getMonth() + 1).toString() + objToday.getDate().toString(); var strStockCode = new String("2002"); insertAccess(strTrnDate, strStockCode, parseHTML(strTrnDate, strStockCode, getHttp(strStockCode))); } catch (e) { WScript.Echo("執行過程有誤,錯誤訊息:" + e.description); } ]]> </script> </job> </package>
與前一篇文章「在WSH環境下存取Access資料庫」的作法對照,寫法更加簡潔,至少不用自己計算單引號的位置與個數(這是很容易出錯的地方)。看來想在WSH環境下跟資料庫打交道,把ADODB物件的用法摸熟會是一個比較好的資料處理方式。
補充記錄:在上面的程式碼第5行中所載入的adojavas.js檔案是藉由修改ASP環境所提供的adojavas.inc檔案而來;如果電腦上有安裝ADO元件,可以在C:\Program Files\Common Files\System\ado資料夾下找到adojavas.inc檔案,把副檔名修改成js,並將檔案內容前後的「<%」與「%>」符號移除,就可以直接引用該檔案已經定義好的常數值(例如程式碼第145行的adOpenStatic),省去自行訂義的麻煩。
沒有留言:
張貼留言