2011年11月30日 星期三

設定 Oracle Client 的 NLS_LANG

前一陣子透過 Oracle Client 讀取 Oracle 資料
發現有些 View 的資料永遠讀不出來
最後發現是因為 Web Server 上 Oracle Client 的 NLS_LANG 設的和 Database 不一樣

只要加上下面這一行, 就一切 OK~
   ' AMERICAN_AMERICA.ZHT16BIG5 是我們 Database 上的設定 
   Environment.SetEnvironmentVariable("NLS_LANG", "AMERICAN_AMERICA.ZHT16BIG5")

使用 7-Zip 壓縮檔案

最近要壓縮 Email 附件檔
所以就挑了 7-Zip 來使用(免費)
這邊就記錄一下使用方式

   Dim p as new Diagnostics.Process()      
   ' 7z.exe 的路徑
   ' 也可以將 7z.exe 直接 Copy 到程式資料夾下
   p.StartInfo.Filename = "C:\Progra~1\7-Zip\7z.exe"
   ' a : 加入壓縮檔
   ' -tzip : 以 zip 方式壓縮
   ' -v3m : 每 3 MB 切割一個壓縮檔
   ' ZipFiles : 要壓縮的資料夾或檔案名稱 (可使用相對或絕對路徑)
   p.StartInfo.Arguments = "a -tzip -v3m ZipFiles"
   p.Start()
   p.WaitForExit()  ' 等待壓縮完成才進行之後的程式段

7-Zip 的相關參數設定可參考 [此處]

2011年9月14日 星期三

ASP 呼叫 .NET Web Service

為了讓 ASP 呼叫 .NET 的 Web Service
上網查了好久的資料
查到有 2 種方式可以達成
   1. 使用 XMLHTTP 呼叫
   2. 使用 SOAP 呼叫
最後決定用 XMLHTTP 的方式呼叫
因為 SOAP 要另外在 ASP 端安裝 SOAP Toolkit

在這邊記錄一下 XMLHTTP 呼叫 Web Service 的方法

<%
   Set objHttp = Server.CreateObject("MSXML2.XMLHTTP")
   Set xmlDOC = Server.CreateObject("MSXML.DOMDocument")

   ' Web Service 網址 (最後面加要呼叫的Function Name)
   ws_url = "http://localhost/TestWebService/Service.asmx/Add"

   ' Web Service 要傳入的參數
   ws_params = "Param1=" & 1 & "&Param2=" & 3

   ' Web Service 的 web.config 要在 <system.web> </system.web> 中設定
   ' <webservices>
   '    <protocols>
   '        <add name="HttpPost"/>
   '        <add name="HttpGet"/>
   '    </protocols>
   ' </webServices>
   objHttp.Open "POST", ws_url, False
   objHttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
   objHttp.Send(ws_params)
   xmlDOC.load(objHttp.responseXML)

   if objHttp.Status = 200 then
      xmlStr = xmlDOC.xml
      Response.Write Replace(Replace(xmlStr,"<","&lt;"),">","&gt;")
   else
      Response.Write "Error : " & objHttp.StatusText & "(" & objHttp.Status & ")"
   end if
%>

2011年8月5日 星期五

SQL Server 建立 Oracle 連結伺服器

記錄一下在SQL Server 建立 Oracle 連結伺服器要注意的地方.

安裝好 Oracle Client 後
就可以到SQL Server建立「Oracle Provider for OLE DB」的連結伺服器
設定畫面如下:


測試連接也都正常


但是一下OPENQUERY查詢,就發生錯誤

最後終於找到原因:Provider要設定InProcess

最後,記得要將連結伺服器刪除重新建立,
這樣InProcess才會生效.

可參考下列資料(雖然說明有些都看不懂):
MSDN-OPENQUERY (Transact-SQL)
MSDN-連結的伺服器屬性(提供者選項頁面)

2011年5月12日 星期四

T-SQL 計算日期的週別

這邊記錄一下用 T-SQL 計算週別的公式

如果以星期日 ~ 星期六為一週的話
直接用 datepart(wk, @TargetDate) 就可以抓出正確的週別了

但是如果是星期五 ~ 星期四為一週
或星期一 ~ 星期日為一週呢?

可以利用下面的公式算出對應的週別

@TargetDate 是要查詢的日期
@StartNo 是指星期幾開始
(ex. 星期五 ~ 星期四為一週, @StartNo = 5)

   case when (datepart(dy, @TargetDate) - @StartNo) <= 0 then 1
   else datepart(wk, @TargetDate - @StartNo) end

2011年3月22日 星期二

寫支自動通報 Windows Tasks 執行結果的程式

Server 上通常都掛載了一堆的 Windows Tasks
當每天要監控一堆 Server 的 Windows Tasks 就是件累人的事
透過 VB.NET 寫一支自動通報執行結果的程式
把各 Server 的 Windows Tasks 執行結果 Email 出來
應該會省點功...

首先利用 schtasks.exe 將 Windows Tasks 的執行狀況匯出為 csv
所以我寫了一隻 .bat 來做這件事
要注意的是, 我這邊實現的環境是 Windows Server 2003
Win7 的 schtasks.exe 匯出的格式和 Windows Server 2003 不太相同
如果要在 Winy 環境上實現, 可能要再花一些時間分析匯出的 csv

TasksToCSV.bat 的內容 :
   schtasks -query -fo csv -v > Tasks.csv

接下來就是 Coding Time 了
就僅針對產生 csv 及擷取內容的方法記錄
Imports System.IO
Imports System.Diagnostics
Imports System.Text

Private Sub GenerateTaskCSV()
   ' 清除舊的 CSV
   Dim fiCSV As New FileInfo(Directory.GetCurrentDirectory() & "\Tasks.csv")
   If fiCSV.Exists = True Then
      fiCSV.Delete()
   End If

   ' 將 Windows Tasks 匯入新的 CSV
   Dim p As Process = Process.Start("TasksToCSV.bat")
   ' 等待 .bat 執行結束
   p.WaitForExit()
End Sub

Private Function GetMailContent(ByVal FilePath As String) As StringBuilder
   Dim sbMailContent As New StringBuilder
   ' 設定要查詢的欄位
   Dim aryColumns() As String = {"主機名稱", "工作名稱", "狀態", "上次執行時間"}
   Dim intServerNamePos As Integer = 0
   Dim intStatusPos As Integer = 2
   Dim aryColPos(aryColumns.Length) As Integer
   Dim strLine As String = ""

   sbMailContent.AppendLine("<table>")
   sbMailContent.AppendLine(" <tr>")
   For t As Integer = 0 To aryColumns.Length - 1
      sbMailContent.AppendLine("<th>" & aryColumns(t) & "</th>")
   Next
   sbMailContent.AppendLine(" </tr>")

   Dim srReader As New StreamReader(FilePath, Encoding.Default)
   strLine = srReader.ReadLine()
   If Len(strLine) > 0 Then

      ' 找要查詢欄位的位置
      Dim aryHeader() As String = strLine.Split(""",""")
      For c As Integer = 0 To aryColumns.Length - 1
         For h As Integer = 0 To aryHeader.Length - 1
            If aryColumns(c) = Replace(aryHeader(h), """", "") Then
               aryColPos(c) = h
               h = aryHeader.Length
            End If
         Next
      Next

      strLine = srReader.ReadLine()
      While (Len(strLine) > 0)
         ' 如果抓出來的行資料最後不是雙引號結尾, 表示資料跨行
         ' 就繼續抓出下一行, 直到以雙引號結尾
         While (Right(strLine, 1) <> """")
            strLine = strLine & srReader.ReadLine()
         End While
         Dim aryContent() As String = strLine.Split(""",""")
         Dim strColumnValue As String = ""

         sbMailContent.AppendLine(" <tr>")
         For c As Integer = 0 To aryColumns.Length - 1
            If Len(ServerName) = 0 AndAlso c = intServerNamePos Then
               ServerName = Replace(aryContent(aryColPos(c)), """", "")
            End If
            strColumnValue = Replace(aryContent(aryColPos(c)), """", "")
            sbMailContent.AppendLine("<td>" & strColumnValue & "</td>")
         Next
         sbMailContent.AppendLine(" </tr>")
         strLine = srReader.ReadLine()
      End While

   End If
   sbMailContent.AppendLine("</table>")

   Return sbMailContent
End Function

2011年3月10日 星期四

將 SQL Server 2005 SSIS 封裝設為範本

今天在查怎麼將設計好的 SQL Server 2005 SSIS 封裝設為範本
就順便記錄下來 :

1.將設計好的 SSIS 建置起來
2.將建置的封裝檔 (*.dtsx) copy 到
C:\Program Files\Microsoft Visual Studio 8\Common7\
IDE\PrivateAssemblies\ProjectItems\
DataTransformationProject\DataTransformationItems\

3.在專案新增項目, SQL Server Integration Services 專案項目中就會出現此範本
4.參考 TechNet 的說明, 改變封裝的 Name 與 ID 值

[參考TechNet]

話說我在查 TechNet 的資料時, 一直看錯
以為只要 copy 到
C:\Program Files\Microsoft Visual Studio 8\Common7\
IDE\PrivateAssemblies\ProjectItems\
DataTransformationProject\
就好, 害我試了半天都叫不出範本

SQL Server 2005 備份 Analysis Service DB

SQL Server Analysis Service DB
透過 XMLA 命令就可以做到排程備份
將粗體字的部份替換成實際資料即可

<Backup xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
   <Object>
      <DatabaseID>[Analysis Service DB Name]</DatabaseID>
   </Object>
   <File>[FilePath].abf</File>
   <AllowOverwrite>true</AllowOverwrite>
</Backup>

[參考小狐狸部落] [參考TechNet]

2011年1月31日 星期一

VB.NET 產生 Excel 圖表另存圖片

記錄一下怎麼產生 Excel 圖表並另存成圖片

1.開啟一個空白 Excel, 將要填的資料格式都準備好, 並插入想要的圖表在裡面
2.將 Excel 儲存為 Template.xls 放入專案 \bin\debug\ 下
3.撰寫 VB.NET 程式段填寫資料 (圖表會隨資料異動而改變)

'開啟 Template Excel
Dim strTemplatePath As String = Directory.GetCurrentDirectory & "\Template.xls"
Dim xlsApp As New Application()
Dim xlsWorkBook As Workbook = xlsApp.Workbooks.Open(strTemplatePath)
Dim xlsWorkSheet As Worksheet = CType(xlsWorkBook.Worksheets("Sheet1"), Worksheet)

'填入 Excel 資料
..................................

'另存為 Html (產生圖表圖片)
Dim strHtmlName As String = Directory.GetCurrentDirectory & "\Chart.htm"
xlsWorkBook.SaveAs(strHtmlName, XlFileFormat.xlHtml)

'關閉 Excel
xlsWorkBook.Saved = True
xlsApp.Quit()
xlsApp = Nothing
GC.Collect()
GC.WaitForPendingFinalizers()

這樣 \bin\debug\ 下就會多了個 Chart.htm 檔案及 Chart.files 資料夾
Chart.files 資料夾下會有個 image001.gif 圖片
這就是我們要的圖片檔了
(p.s 如果 Template.xls 裡有多張圖表, 會依序命名為 image001, image002...)

2011年1月12日 星期三

SQL Server 2005 備份

完整備份 : 備份 DB 的 .mdf 及 .ldf

差異備份 : 必須先產生完整備份
       備份完整備份至目前為止所有異動過的 .mdf 資料
       適用於 : 資料量成長較低, 但交易頻繁的 DB, 且交易歷程較不重要的 DB

交易記錄備份 : 必須先產生完整備份
          備份自完整備份/差異備份/上次交易記錄備份到目前為止所有異動過的 .ldf 資料 (見附圖)
          適用於 : 資料量急速成長的 DB

Command :
--截斷交易記錄
backup log DBName with truncate_only

--壓縮資料庫
dbcc shrinkdatabase(DBName, truncateonly)

--壓縮檔案
dbcc shrinkfile(DBName_log, Default_Size)

--完整備份
backup database DBName to disk = 'D:\Folder\xxxxxxxxxxxxx.bak'

--差異備份
backup database DBName to disk = 'D:\Folder\xxxxxxxxxxxxx.bak' with differential

--交易記錄備份
backup log DBName to disk = 'D:\Folder\xxxxxxxxxxxxx.trn'