2009年12月26日 星期六

了解Email Headers所代表的意義

我是從Reading Email Headers 這邊看到的,解說的很詳盡,我稍微把我理解的寫出來,看不懂我寫的人,只能說抱歉囉,我表達能力不好,建議各位還是去看原文吧

一般的郵件傳輸的過程至少經過4台電腦,怎麼說呢,當使用者發送郵件,會在使用者自己的電腦上產出訊息,然後訊息會先送到你指定寄件用的Mail Server(可能是你ISP用的或公司的),此時使用者的電腦已完成它的發送工作,但是Mail Server還沒完成他的工作,他會幫你找到收件者的Mail Server,跟她溝通然後將訊息傳送給她才算完成,這訊息會待在第二台Mail Server上,直到收件者讀取該訊息,將訊息下載到收件者的電腦後刪除,整個流程大概是這樣。

2009年12月22日 星期二

使用CDO.Messages來發信,未設定認證(smtpauthenticate)的奇怪現象

基本上使用CDO.Messages來發信,可以選擇使用本機SMTP service或是遠端的SMTP,但我想大多數應該是用遠端的方式吧,畢竟不是每台Sever都有裝SMTP service的

我平常在正式環境使用都是用遠端,然後有啟用基本認證,要輸入帳號密碼後才能寄,這樣幾乎不管到哪裡,程式都能寄信,到目前為止我還沒遇過有問題的,相關程式碼在 http://adalf0722.blogspot.com/2008/12/vbs.html

2009年12月20日 星期日

非sysadmin在SSMS中開啟Data Transformation Services的錯誤

資料庫為SQL 2000,只要在SQL Server 中有有效的登入權限的使用者,用Enterprise Manager(EM)開啟本機封裝不會有問題,不需要額外設定權限,但同樣的使用者若是用SQL 2005以後的管理工具SSMS中開啟舊版的Data Transformation Services就會跳出如下錯誤

SELECT 使用權限在物件 'sysdtspackages',資料庫 'msdb',擁有者 'dbo' 上被拒絕。 (Microsoft SQL Server, 錯誤: 229)

2009年11月10日 星期二

如何用sp_executesql將Select的值輸出

剛好要動態組出Select陳述式,欄位是會變的那種,若不需把Select出的值輸出到一個變數,其實可直接用exec(@cmd)就好,但是若需要輸出就得用sp_executesql了,可是一直試都失敗,輸出的值都是Null,然後SQL Server線上說明又沒提什特殊設定,好在網路很方便,原來只要在sp_executesql的第二個與第三個參數那加上out就行了,下面是一個簡例,分享給剛好不知道的人

2009年10月9日 星期五

DTS的owner與owner_sid不一致的問題

最近同事反應SQL 2000的某個DTS無法儲存,會出現"Only the owner of DTS Package or a member of the sysadmin role may create new versions of it."的錯誤,意思就是只有此DTS的擁有者或是系統管理員的身分才能建立新的版本,目前那個DTS的owner不是他,那我改掉應該就行

上網查了一下發現可以用sp_reassign_dtspackageowner [@name =] 'name',[@id =] 'id',[@newloginname =] 'newloginname'來改變DTS的owner

2009年8月15日 星期六

取得DTS的屬性值與全域變數

因為之前設計了一個DTS定期撈取執行失敗的工作排程,然後會寄送mail通知相關負責人,頂多附上歷程紀錄的相關資訊,有時資訊一多,根本看不出來錯在哪裡,雖然封裝屬性裡可以設定錯誤紀錄檔,但是我不知怎麼取得相關資訊,我在資料庫裡找了好久都找不到,經過一段時間尋找,終於讓我發現啦,原來用VB Script可以取得該封裝的相關資訊啊,分享給各位囉

2009年8月5日 星期三

msxml3.dll 錯誤 '800c000e'

最近同事反應他的ASP程式執行出錯,錯誤訊息如下,之前是正常的說
msxml3.dll 錯誤 '800c000e'
發生安全性問題。

程式碼簡略如下
Set objXMLHTTP = Server.CreateObject("Microsoft.XMLHTTP")

objXMLHTTP.Open "GET", URL, flase
objXMLHTTP.setRequestHeader "Content-Type", "text/html"
objXMLHTTP.setRequestHeader "charset", "big5"
objXMLHTTP.send 

剛好最近系統移轉,想說會不會是msxml3.dll沒裝,查了一下在 %windir%\system32下是有的,
再用regsvr32重新註冊一下好了,
結果錯誤還是一樣,難道要設安全性嗎?我倒是沒設過
,想說去下載msxml3重裝,結果錯誤還是一樣,真是見鬼

忽然想起該不會是找不到Microsoft.XMLHTTP吧,
因為CreateObject函數會先檢查註冊表HKEY_CLASSES_ROOT\Microsoft.XMLHTTP 下的子鍵,
一查果然HKEY_CLASSES_ROOT下沒有Microsoft.XMLHTTP囉,
那反查一下msxml3.dll在HKEY_CLASSES_ROOTHKEY_CLASSES_ROOT\CLSID下的哪個機碼是跟XMLHTTP有關的,
結果在HKEY_CLASSES_ROOT\CLSID\{AFB40FFD-B609-40A3-9828-F88BBE11E4E3}下發現Server XML HTTP 3.0囉,
再用這個CLSID追查下去,最後就查到HKEY_CLASSES_ROOT\Msxml2.ServerXMLHTTP.3.0

可見是設錯啦

解決辦法
Set objXMLHTTP = Server.CreateObject("Microsoft.XMLHTTP")
換成
Set objXMLHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")

2009年7月3日 星期五

啟用IIS6隔離模式對CDO.Message的影響

因為不明的原因造成IIS6常常重啟,不得已只好開啟隔離模式(用 IIS 5.0 隔離模式執行 WWW 服務),結果奇怪的事發生了,原本ASP可以發送mail的,突然不能發送,還有錯誤訊息,把隔離模式取消,就可以發送了,很怪吧(CDONTS也一樣,可參考我另一篇)

程式如下


Set objEmail = CreateObject("CDO.Message")
objEmail.From = "寄件者"
objEmail.To = "收件者"
objEmail.Subject = "CDO.Message test"
objEmail.Textbody = "test"
objEmail.Send
Response.write "使用CDO.Message發信成功"

錯誤訊息


CDO.Message.1 錯誤 '80040220'
"SendUsing" (?C°e‥I¥I) 3]cw-EμLRA!C
/mis331.asp, 列8
解決辦法

objEmail.Send 前,加入下列四行即可
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"localhost"
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update

2009年7月2日 星期四

啟用IIS6隔離模式對CDONTS.NewMail的影響

先說win2003預設已不支援CDONTS.NewMail了,建議是用CDO.Message囉,但若還是堅持要用,請自行從別台機器拷貝cdonts.dll然後再註冊就可使用!

因為不明的原因造成IIS6常常重啟,不得已只好開啟隔離模式(用 IIS 5.0 隔離模式執行 WWW 服務),結果奇怪的事發生了,原本ASP可以發送mail的,突然不能發送,還有錯誤訊息,把隔離模式取消,就可以發送了,很怪吧 (CDO.Message也是,可參考)

程式如下
Set objEmail = CreateObject("CDONTS.NewMail")
objEmail.From = "寄件者"
objEmail.To = "收件者"
objEmail.Subject = "CDONTS.NewMail test"
objEmail.body = "test"
objEmail.Send
Response.write "使用CDONTS.NewMail發信成功"

錯誤訊息如下

Microsoft VBScript 執行階段錯誤 錯誤 '800a0046'
沒有使用權限
/mis33.asp, 列8

解決辦法

在IIS管理員的SMTP按右鍵選內容
在安全性頁籤新增下列兩各的權限就OK
IUSR_電腦名稱
IWAM _電腦名稱

2009年6月29日 星期一

BitComet黃燈阻塞的解決辦法

1.先確定選項裡有監聽Port,打開防火牆,及映射囉


2. 再確認防毒軟體有沒有檔BitComet,有的會檔,自己去檢查一下,我自己用小紅傘是沒檔啦

3.重點來囉,如果確認過前兩步驟還是沒變綠燈的話,我猜你的情況應該與我相同,就是有用IP分享器的關係,只要設定一下虛擬伺服器就ok啦,記得內外部的Port要跟BitComet裡監聽Port一樣的就行啦


4. 重開BitComet就變綠燈

2009年5月6日 星期三

交易記錄檔備份失敗

今天收到"資料庫維護計劃-交易記錄檔備份"竟然失敗的訊息,真是詭異,因為是第一次看到,更詭異的是看作業的錯誤訊息竟然看不出所以然,如下:



以下列使用者的身分執行: Domain\administrator。 sqlmaint.exe 失敗。 [SQLSTATE 42000] (錯誤 22029). 步驟失敗。


看那錯誤我誤以為那身分是不是帳密有改過, 問我們MIS確定是沒有的,只好上網查,原來真正錯誤訊息要去看維護計劃歷程記錄失敗的項目,才找到原因,原來是我早上動到某個資料庫的復原模式的關係啊

2009年4月19日 星期日

DTS的工作順序也許不是你想的那樣

之前設計DTS時,通常是每各轉換資料工作,有自己獨立的來源與目的地,然後一個轉換資料工作執行成功後,才作下一各轉換資料工作,中間用成功串連起來,結果昨天偷懶一下,試著兩個工作共用同一個來源與目的地,如下圖


原本以為執行的順序是[4002SQL1(1)]跟[4002SQL2(3)]都執行成功了,才執行[SQL2TXT3(2)]的,結果不是,如下圖

竟然[SQL2TXT3(2)]比[4002SQL(3)]早執行,要是[SQL2TXT3(2)]的工作,其中有資料是要靠[4002SQL2(3)]來傳輸的,那不就會有問題了嗎?
早知道就不要偷懶,乖乖一個一個的分開設比較安全!

後來發現,應該是我成功的工作流程屬性沒特別設定優先順序造成的,我從沒特別去設它...@@...如下圖以至於[4002SQL1(1)]完就接著作[SQL2TXT3(2)],所以那我再加入另一各步驟進來
執行後,終於跟我想的一樣了!!

2009年4月18日 星期六

列出FTP虛擬目錄

根據IIS的說明主題裡有提到
下列命令是顯示Test Downloads FTP 站台之根目錄中的虛擬目錄
iisftpdr /query "Test Downloads"
Alias Physical Root
=====================
/Scripts  C:\Libraries\Scripts

2009年4月1日 星期三

如何在 SQL Server 的執行個體之間傳送登入和密碼

不管是要移動或是複製資料庫到不同版本的Server上,登入與密碼的傳送就很重要,可參考KB246133,建立 sp_help_revlogin 預存程序後,執行下列陳述式,用以產生原始 SID 和密碼的登入指令
EXEC master..sp_help_revlogin

注意kb246133裡有寫適用於下列案例:

  • 將登入和密碼從 SQL Server 7.0 傳送至 SQL Server 7.0。
  • 將登入和密碼從 SQL Server 7.0 傳送至 SQL Server 2000。
  • 將登入和密碼從 SQL Server 7.0 傳送至 SQL Server 2005。
  • 在執行 SQL Server 2000 的伺服器之間傳送登入和密碼。
  • 將登入和密碼從 SQL Server 2000 傳送至 SQL Server 2005。
若你誤以為在SQL Server 2005 間傳送登入和密碼也是行的,那你會犯跟我一樣的錯誤,在建立sp_help_revlogin 預存程序後,執行EXEC master..sp_help_revlogin可是會收到下列錯誤的,因為2005已經沒有sysxlogins這個表囉
訊息 208,層級 16,狀態 1,程序 sp_help_revlogin,行 12
無效的物件名稱 'master..sysxlogins'。


若想要在SQL Server 2005 間傳送登入和密碼,需參考KB918992的喔,不要搞混了,其實KB246133也有提到,只是我都沒注意到...

2009年3月28日 星期六

無法取消列印

送出列印後,發現印表機沒反應,打開印表機佇列,發現有文件卡住,想取消又刪除不掉,一直停在"刪除 - 列印"狀態,通常只能重開機囉

後來發現其實有不用重開機的方法,將以下的script存del_print_Doc.bat,再執行即可,我測試過真的有效喔

@echo off
::停止印表機服務
echo 正在停止印表機服務...
Net Stop spooler
echo.
::清除所有列印的佇列
echo 正在清除所有列印佇列...
echo y del %systemroot%\system32\spool\printers\*.*
::重新啟動印表機服務
echo.
echo 正在啟動印表機服務...
Net Start Spooler
echo.
echo 您再開啟印表機將看到佇列資料已經被清空喔
echo 請 按 任 意 鍵 繼 續 ...
pause >nul

2009年3月4日 星期三

550 5.7.1 Unable to relay

使用JAVAMAIL寄信,結果出現下列錯誤
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
class javax.mail.SendFailedException: 550 5.7.1 Unable to relay

意思就是你的mail server不允許你經由它寄送外部郵件,寄送內部郵件應該沒問題啦,反正應該是驗證的問題囉,不是你程式裡沒有設定要驗證就是mail server不讓你驗證,所以請檢查發送mail的程式裡有沒有啟用驗證囉,有啟用通常會用到帳號密碼囉,不過像我的情況是,該系統被加入relay清單裡,exchange似乎強制不讓我驗證,就算程式有驗證也沒用,解決辦法就是請管理者幫你把該系統從relay清單移除,然後AP server記得重啟或AP重新部署,有時不這麼作,會有cache造成怪怪的問題喔!!

可參考javamail的FAQ,有相關說明
When I try to send a message, why do I get javax.mail.SendFailedException: 550 Unable to relay for my-address?

其實若使用JAVAMAIL寄信發生問題,我發現開啟debug模式去看與mail server通訊的細節,會比較清楚問題發生在哪喔,附上debug模式的記錄,其中綠字是我的補充說明囉

以DEBUG為開頭表示是JavaMail run-time印出來的

此次mail session所使用的Provider
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]

SMTP所使用的參數設定,這邊要注意useAuth是"true"還是"false","true"代表程式有啟用驗證,"false"代表沒有啟用,但是有例外的情況,有時程式明明有啟用,但是這裡還是顯示"false",表示mail server可能不讓你驗證喔,像exchange的話,若系統在relay清單裡,程式有設驗證也沒用喔,這時寄外部郵件會有問題,這是我自己測試很多次得來的結論
DEBUG SMTP: useEhlo true, useAuth false

這裡是顯示試圖連接mail.test.com.tw的25port
DEBUG SMTP: trying to connect to host "mailt.test.com.tw", port 25
這裡就表是已連接到囉,網路是通的
220 HCS03.mail.local Microsoft ESMTP MAIL Service ready at Fri, 20 Feb 2009 11:51:17 +0800
DEBUG SMTP: connected to host "mailt.test.com.tw", port: 25
使伺服器可以表明自己支援擴展簡單郵件傳輸協定 (ESMTP) 命令
EHLO sva511

250-HCS03.mail.local Hello [192.168.107.2]

下面就是支援哪些命令囉
250-SIZE 10485760

250-PIPELINING
250-DSN

250-ENHANCEDSTATUSCODES
250-STARTTLS
250-X-ANONYMOUSTLS

250-AUTH NTLM LOGIN

250-X-EXPS GSSAPI NTLM

250-8BITMIME

250-BINARYMIME
250-CHUNKING
250-XEXCH50
250 XRDST
DEBUG SMTP: Found extension "SIZE", arg "10485760"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "X-ANONYMOUSTLS", arg ""
DEBUG SMTP: Found extension "AUTH", arg "NTLM LOGIN"
DEBUG SMTP: Found extension "X-EXPS", arg "GSSAPI NTLM"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "XEXCH50", arg ""
DEBUG SMTP: Found extension "XRDST", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:< sender@test.com.tw >

寄件者ok
250 2.1.0 Sender OK
RCPT TO:< receiver22@yahoo.com >

無法幫你轉信給該寄件者
550 5.7.1 Unable to relay
DEBUG SMTP: Invalid Addresses
DEBUG SMTP: receiver22@yahoo.com
DEBUG SMTP: Sending failed because of invalid destination addresses
RSET
250 2.0.0 Resetting

2009年2月26日 星期四

Windows Installer並未正確安裝或windows update無法更新

公司的網管反應有台測試機win 2000 server,常常中毒,我當時用掃毒程式掃了也沒事,但是過幾天後去看,發現掃毒程式每天不定時都會反應掃到一個病毒BAT_FTPER.C,我再想是不是太久沒windows update了,於是就去更新一下,結果失敗...@@

想裝MBSA看看好了,因為MBSA也會告訴你有哪些更新沒裝,結果跳出下列訊息

無法存取Windows Installer
可能是Windows處於安全模式 或是Windows Installer並未正確安裝
請聯絡您的支援人員

解決辦法

1.若要解決windows update無法更新的問題

 a. 安裝Windows Installer 3.0 Redistributable

 b. 重新開機後,就可以正常更新了


2.若要解決Windows Installer並未正確安裝的問題

 regsvr32 %systemroot%\system32\msi.dll

2009年2月22日 星期日

刪除七天前無效的連線

最近有台SQL Server的CPU使用率常常飆高,觀察似乎是連線的數量太多了,有很多連線是程式使用完沒有close的關係,短時間人手不足,沒法修正程式,只好手動清除啦,不過一個一個清太累囉,還是寫段陳述式來清囉

DECLARE @spid int, @SQLstr nvarchar(128)

--僅針對某個登入來清理囉,所以請自行更換"使用者"
DECLARE spids_cr CURSOR FOR
SELECT sp.spid FROM master..sysprocesses sp
LEFT OUTER JOIN master..sysdatabases sd ON sd.dbid = sp.dbid
WHERE sp.loginame='使用者' AND sp.net_address<>''
and sp.last_batch <= DATEADD(dd,-7,getdate())


OPEN spids_cr

FETCH spids_cr INTO @spid

WHILE (@@FETCH_STATUS=0)

BEGIN

SET @SQLstr = 'KILL ' + CAST(@spid AS varchar)

EXEC sp_executesql @SQLstr

FETCH spids_cr INTO @spid

END

CLOSE spids_cr
DEALLOCATE spids_cr

2009年2月12日 星期四

SMTP 550 5.7.1 not permissions as this sender

如果寄信失敗,結果回傳錯誤碼550 5.7.1 ,錯誤訊息跟下面三種情況一樣的話,表示你使用的發信伺服器,有限制寄件者需與帳號一致喔,意思就是若用我的帳號發信,寄件者就不能設成別人,請檢查你的程式寄件者是不是設的與帳號不同!一般發信若是使用SMTP services來寄信是不會有這種困擾的,因為寄件者就算設不存在的也照樣可以寄!

2009年2月11日 星期三

JAVAMAIL範例2(不需認證的smtp)

這個blogger不允許直接貼上完整的jsp程式碼囉,所以我只列出主要的,記得"<"與"%"還有"%"跟">"是沒有空白的喔

< % @page import="java.util.*" % >
< % @page import="javax.mail.*" % >
< % @page import="javax.activation.*" % >
< % @page import="javax.mail.internet.*" % >


< %
String host = "127.0.0.1";
String receiver = "收件人";
String sender = "發信人";
String subject = "主旨";
String mess = "內文success";

boolean sessionDebug = false;

Properties prop = new Properties();
prop.put("mail.smtp.host",host); //指定SMTP server

Session mailsess = Session.getInstance(prop);
mailsess.setDebug(sessionDebug); //是否在控制台顯示debug訊息

Message msg = new MimeMessage(mailsess);
//設定郵件
msg.setFrom(new InternetAddress(sender)); // 設定傳送郵件的發信人
InternetAddress[] address= {new InternetAddress(receiver)}; // 設定傳送郵件的收件者
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject(subject); //設定主題
msg.setText(mess); //設定內文

//發送郵件
Transport transport = mailsess.getTransport("smtp"); //只支持IMAP、 SMTP和 POP3
transport.send(msg);
% >

2009年2月10日 星期二

JAVAMAIL範例1(需要認證的smtp)

最近mail server升級,結果部分系統的發信機制出了問題,所以需要簡單的範例程式來測一下,但是我不會java,只好上網稍微研究了一下囉,簡單的code卻花了我不少時間研究,分享給有需要的朋友,這個blogger不允許直接貼上完整的jsp程式碼囉,所以我只列出主要的,記得"<"與"%"還有"%"跟">"是沒有空白的喔

< % @page import="java.util.*" % >
< % @page import="javax.mail.*" % >
< % @page import="javax.activation.*" % >
< % @page import="javax.mail.internet.*" % >


String host = "發信伺服器";
String receiver = "收件者";
String sender = "寄件者";
String subject = "主旨";
String mess = "內文";
String username = "帳號";
String password = "密碼";

boolean sessionDebug = false;

//Get system properties
Properties prop = System.getProperties();
prop.put("mail.smtp.host",host); //指定SMTP server
prop.put("mail.transport.protocol","smtp"); //設定傳送協定
prop.put("mail.smtp.auth","true"); //設定是否須smtp驗證

// 產生新的Session
javax.mail.Session mailsess = Session.getDefaultInstance(prop);
mailsess.setDebug(sessionDebug); //是否在控制台顯示debug訊息

Message msg = new MimeMessage(mailsess);
//設定郵件
msg.setFrom(new InternetAddress(sender)); // 設定傳送郵件的發信人
InternetAddress[] address= {new InternetAddress(receiver)}; // 設定傳送郵件的收件者
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject(subject); //設定主題
msg.setText(mess); //設定內文

//發送郵件
Transport transport = mailsess.getTransport("smtp"); //只支持IMAP、 SMTP和 POP3
transport.connect(host, username, password); //以smtp的方式登入mail server
transport.sendMessage(msg,msg.getAllRecipients());
transport.close();
% >

2009年2月5日 星期四

FINDSTR進階用法

想搜尋大量文字檔裡的字串,建議FINDSTR一定要學會用,很方便的喔,我這幾天才知道原來有支援一般表示式呢,使用起來更加強大喔

A.利用/G從指定的檔案取得搜尋字串清單(按我看一下會更了解這怎麼用)
  請把下列的"&"替換成shift+\囉,也就是一條直線的管道符號(因blogger把我字給吃了)

findstr /s /i /G:search.txt d:\*.asp & findstr /v /i /G:exclude.txt > c:xx.log

其中 search.txt 是搜尋字串所在的檔案,d:\*.asp加/s是要搜尋D槽下所有asp的檔案,exclude.txt 是要排除的搜尋字串所在的檔案,xx.log則存放搜尋結果。

B.使用一般表示式(Regular Expression)
 以下是FINDSTR所支援的中繼字元,雖沒有很多,但我覺得很夠用囉


 0.跟著我一起練習,會比較了解喔,先把以下綠色文字複製後存成xx.txt,此例是txt是放在f槽,所以下面的語句請自行依情況變換喔


select * from comp
32165469874
select * from accomplish

select * from Comp
546VDFBSF4545
from
select * from comp
select * from COMP
compare


 1.通常若不知道一般表示式怎麼用,想搜尋comp字串,語句可能會長的像下面這行一樣,但是這樣的執行結果會跑出一些我們不需要的結果,如accomplish與compare,如下圖1的地方
findstr "comp" f:\xx.txt
 2. 若知道一般表示式,可以利用"\<"與"\>"來包住comp,限制該字元開頭跟結尾,就可以只找到你要的,就不會跑出accomplish與compare的結果囉,見下圖2的地方
因為這blog會過濾換行字元,所以指令請見圖吧
 3.若只想搜尋comp字串,但是c又不限定大小寫,就可以用中括號來包含字元集合[Cc],意思就是C或c皆可囉,像"[Cc]omp"就是Comp與comp都可,見下圖3
findstr "[Cc]omp" f:\xx.txt


 4若想找開頭為comp的字串,c不分大小寫,見下圖4
findstr "\<[Cc]omp" f:\xx.txt
 5.若想找結尾為comp的字串,c不分大小寫,見下圖5
findstr "[Cc]omp\>" f:\xx.txt
 6.若想找comp的字串,全部不區分大小寫,見下圖6,其實也是可以用"/i" 的
findstr "[Cc][oO][Mm][Pp]" f:\xx.txt


 8.若想找"from comp"字串,中間有一個空格的,可不能直接用"from comp"喔,那可是會找出from或comp的字串啊,所以得用中繼字".",如"from.comp",但是找出的結果可能會有很多,因為"."是萬用字啊,可以替換成任何字元,如圖8
因為這blog會過濾換行字元,所以指令請見圖
 7. 前面已提過"."表示搜索的條件是任意字元,而"*"在一般表示式中的作用不是任意字元喔,而是表示左側字元可以重複的意思,"*"表示重複的次數可為零次或者多次。所以若搜尋字串中使用".*",表示在那字串中可以夾雜0個,1個或很多個任意字元的喔,見下圖7,"from.*comp"的意思就是"from"與"comp"間可以含一個空白或很多空白的意思,在此例囉


 9.範圍[a-z]這種的我就不介紹,因為用起來怪怪的,似乎有問題,網路上我也查到似乎是各bug(Ranges [a-z] and [A-Z] perform INCONSISTENTLY in 2K/XP)


 10."^" 表示行首,"^from"就表示要找一行開頭必須為"from"的囉,其餘的皆不符合,語句如下
findstr "^from" f:\xx.txt
from

 11."$"表示行尾,"comp$"即表示要找一行結尾必須為"comp"的囉
findstr "comp$" f:\xx.txt
select * from comp
select * from  comp

c.利用for迴圈

 介紹到這,當你已了解我前面介紹findstr使用檔案內容當作搜尋清單及一般表示式這兩種用法之後,你就可以把他們結合起來用囉,搜尋清單的內容使用一般表示式,然後如果你再用上for迴圈的話,就可以作到依收尋字串分成數個搜尋結果檔囉!要不然結果全都導入一個檔,之後若要在分類很麻煩的,不如一開始就作好它!那怎麼用呢?語句如下,是一行喔不是兩或三行!要存成bat檔喔! 請把下列的"&"替換成shift+\囉,也就是一條直線的管道符號(因blogger把我字給吃了)
for /f "tokens=1,2 delims=," %%i in (c:\search.txt) do findstr /S /N /R "%%j" D:\svn_meta\*.j* & findstr /v /i /G:exclude.txt > d:%%i.log

我這邊的例子,假設我想找"from travel"及"from zip"這兩個字串,分別希望搜尋結果是導入travel.log及zip.log,search.txt的內容應該長的像下面這兩行
travel,from.travel
zip,from.zip


若看不懂,建議先看我令一篇For的應用

2009年2月4日 星期三

FOR語句的應用

可能很多人不知道在Batch裡也有迴圈可以運用喔,我個人覺得這功能非常強大,雖然我只會簡單的,但有時可幫助我節省不少工作時間呢!
  可在命令列下"for /?"得到詳細資訊喔

0.基本應用(沒有啟用擴充命令)
 就是手動去指定迴圈範圍,語句如下
 FOR %variable IN (set) DO 指令 [command-parameters]

 例子1:如何快速找出硬碟CDE槽的剩餘可用空間 。
 語句1: 請把&替換成shift+\囉(blogger把我字給吃了)
for %i in (c d e) do @dir %i: & find "位元組可用"
 22 個目錄 6,034,595,840 位元組可用
 15 個目錄 1,634,000,896 位元組可用
 8 個目錄 3,506,417,664 位元組可用
 補充1:@ 只是讓輸出結果不包括 dir命令本身而已

 例子2:參考刪除隨身碟病毒裡的一段,內容意思是解除所有硬碟內的autorun.inf及ntdelet.com的屬性,然後刪除它們並隱藏訊息 。
 語句2:
for %%x in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
attrib -r -s -h -a %%x:\autorun.inf >nul 2>nul&&attrib -r -s -h -a %%x:\ntdelect.com >nul 2>nul
del %%x:\autorun.inf /q /f >nul 2>nul&&del %%x:\ntdelect.com /q /f >nul 2>nul )
 補充2:&&的意思是前面命令成功才接著作後面的命令,各位注意可以用小括號來包更多的命令喔,如果要在批次程式中使用 FOR 指令,請指定 %%variable,而不要指定%variable

1.用/R參數列舉所有目錄
 
語句如下
 FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

 例子3:用for來實現與dir /s /b E:\test\*.txt一樣的結果 。
 語句3:
for /R E:\test %i in (*.txt) do echo %i
 補充3:運用得當就可以對當前目錄下所有檔(包括子目錄裏面的檔)進行操作,像例子4

 例子4:用Subversion版控來管理程式碼時,若要將某各版本全部取出,往往每層目錄裡都含有".svn"的隱藏目錄,對用來上線來說,那些目錄都是多餘的,此時就可以利用for /r來清除這多餘目錄囉。

 語句4:
for /R d:\33 %i in (.) do @if exist %i\.svn rd /s /q "%i\.svn"
 補充4:如果 set 只是單一句點 (.) 字元,它只會列舉樹狀目錄結構喔。然後用if exist來判斷的原因是因為for只是機械化的列舉目錄,在此例底下不一定有.svn目錄,所以加判斷會安全點。最後因為rd /s /q這指令太可怕了,使用前最好先替代成echo看一下,要不然執行錯誤可是很慘的,像是例子3那樣。差點忘了一點,列舉目錄結構會多一層".",像"d:\33\cat\.",但這並不影響執行結果喔。

2. 用/F參數將檔案內容作為迴圈範圍
 語句如下
 
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]

 例子5:假設我有一個jj.txt檔案列表,我想連同檔案目錄的架構一起複製到c槽,檔案列表如下

c:\temp\a1.txt
c:\temp\test\a2.txt
c:\temp\test\f\a3.txt
c:\temp\bbb\a4.txt

 語句5:
for /f %%i in (C:\jj.txt) do (xcopy %%i c:%%~pi /Y)
 補充5:只要是 %~ 開頭的操作符號,都是檔案名的分離操作,具體請看 for /? 或語句7。

3.用/F參數將命令結果當作迴圈範圍
 語句如下
 
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

 例子6:把date /T輸出的"2009/02/05 星期四"拆掉然後轉換成"2009-02-05"
 語句6:
for /f "tokens=1,2,3 delims=/ " %i in ('date /T') do echo %i-%j-%k
2009-02-05
補充6:此例用到"options"的額外參數,"delims=xxx"指分隔符號的集合,此例分隔符號是"/"與" ",意思是把"2009/02/05 星期四"依分隔符號拆成"2009","02","05"等。"tokens=x,y,m-n"是變數指定的意思,此例是把拆出來的第一個變數指定給%i,第二個給%j,依此類推囉

4. 使用%~來加強完整檔案路徑的分離功能

 直接看語句與結果比較快啦
 語句7:
for /f "delims=" %%i in ("C:\WINNT\system32\drivers\etc\lmhosts.sam") do (
echo.
echo 一個完全符合的路徑名稱 %%~fi
echo 磁碟機字元 %%~di
echo 路徑 %%~pi
echo 檔名 %%~ni
echo 副檔名 %%~xi
echo 路徑只包含短檔名%%~si
echo 檔案屬性 %%~ai
echo 檔案的日期時間 %%~ti
echo 磁碟機字元與路 %%~dpi
echo 檔名與副檔名 %%~nxi
echo 含短檔名的完全路徑 %%~fsi)


一個完全符合的路徑名稱 C:\WINNT\system32\drivers\etc\lmhosts.sam
磁碟機字元 C:
路徑 \WINNT\system32\drivers\etc\
檔名 lmhosts
副檔名 .sam
路徑只包含短檔名C:\WINNT\system32\drivers\etc\lmhosts.sam
檔案屬性 --a------
檔案的日期時間 03/06/26 08:00p
磁碟機字元與路 C:\WINNT\system32\drivers\etc\
檔名與副檔名 lmhosts.sam
含短檔名的完全路徑 C:\WINNT\system32\drivers\etc\lmhosts.sam


5. 用/L參數來指定起始值終值的迴圈範圍
 這個跟一般程式很像囉,語句如下
 FOR /L %variable IN (start,step,end) DO command [command-parameters]

 例子8:假設我想ping一段ip範圍,如11.111.2.115~11.111.2.130,如有回應就印出該ip ok之類的
 語句8: 請把一個的"&"替換成shift+\囉,連續兩個的不用替換(blogger把我字給吃了)
for /L %%i in (115,1,130) do ping -n 1 11.111.2.%%i & find "reply" /i && echo 11.111.2.%%i ok

RealVNC的小技巧

這兩個小技巧,知道的人似乎不多,分享給各位囉

1.如何同時允許兩個連線連入,也就是先連入的不會被後來連入的給斷線喔
 a .執行VNC Viewer後,先不要急著按[OK],先按[Options]

  b .在VNC Viewer Options的設定畫面,先切換到[Misc]頁籤,將[Shared connection]打勾,然後就可以按下[確定],預設是不會打勾的,所以預設是後連入的會把先連入的給斷線囉
 c.就這各設定,很簡單吧

2.VNC如何像遠端桌面一樣,可以一台存成一個捷徑,下次直接點選捷徑就幫你連入呢?

用batch就可以達成囉,將下列兩行存成server1.bat,自行替換IP位址囉,也很簡單

cd "C:\Program Files\RealVNC\VNC4\"
start vncviewer.exe 10.122.2.12

2009年2月3日 星期二

自訂sp_who2加強版

  最近遇到有台DB主機的CPU使用率常常滿載,觀察DB的活動監視器,發現有過多Connection似乎沒有colse,這是不好的現象,那得先找出相關的是哪些Connection囉,SQL 2000本身只提供sp_who與sp_who2這兩個遇存程序來觀察,但都沒提供相關Connection的陳述式的資訊,總不可能再一個一個透過DBCC INPUTBUFFER來查吧,先上網找找有沒有人寫好的加強版,有是有啦,不過不是很合自己用,那就自己來自訂一個吧

--只適用SQL 2000,若要用在2005以後版本請看最後一行
USE [master]
GO
IF object_id('sp_who3') IS NOT NULL
BEGIN
DROP PROC sp_who3
END
GO

CREATE PROC [dbo].[sp_who3]
@loginame sysname = NULL
AS
--參數用法有3種,如下:
--exec sp_who3
--exec sp_who3 '14'
-- 指定spid,只會列出該資料
--exec sp_who3 'active'
-- 指定 ACTIVE。ACTIVE 會從處理序報表中,排除那些等待使用者下一個指令的處理序。
BEGIN

SET NOCOUNT ON

--去除參數頭尾空白
SET @loginame = NULLIF(RTRIM(LTRIM(UPPER(@loginame))), '')

--取得sysprocesses相關資訊後,插入暫存#sp_who3
SELECT sp.spid as 'spid',
sp.status as 'status',
sp.loginame as 'loginame',
NULLIF(RTRIM(LTRIM(sp.hostname)), '') as 'hostname',
sp.blocked as 'blocked',
sd.name as 'dbname',
sp.cmd as 'cmd',
sp.cpu as 'cpu',
sp.physical_io as 'physical_io',
sp.memusage as 'memusage',
sp.open_tran as 'open_tran',
sp.last_batch as 'last_batch',
sp.login_time as 'login_time',
NULLIF(RTRIM(LTRIM(sp.program_name)), '') as 'program_name',
cast('NULL' as nvarchar(255)) as 'eventinfo'
into #sp_who3
FROM master..sysprocesses sp
LEFT OUTER JOIN master..sysdatabases sd ON sd.dbid = sp.dbid

--建立暫存table,儲存dbcc inputbuffer資訊用
CREATE TABLE #inputbuffer (
EventType nvarchar(30),
Parameters Int,
EventInfo nvarchar(255)
)

-- 如果參數指定為ACTIVE則排除那些等待使用者下一個指令的處理序
-- (仿照dbo.sp_who2裡的作法)
IF (@loginame = 'ACTIVE')
DELETE #sp_who3
where LOWER(status) = 'sleeping'
and UPPER(cmd) IN ('AWAITING COMMAND',
'MIRROR HANDLER',
'LAZY WRITER',
'CHECKPOINT SLEEP',
'RA MANAGER')
and blocked = 0

-- 以下是取得額外dbcc inputbuffer的資訊用的
-- 像是T-SQL的內容,這補充dbo.sp_who2所不足的地方
-- cursor Start
DECLARE @spid varchar(30)

DECLARE cur_dbccinputbuffer CURSOR FOR
SELECT CONVERT(VARCHAR(30), spid) FROM #sp_who3

OPEN cur_dbccinputbuffer

FETCH NEXT FROM cur_dbccinputbuffer INTO @spid

WHILE @@fetch_status = 0
BEGIN

TRUNCATE TABLE #inputbuffer

INSERT INTO #inputbuffer
exec('dbcc inputbuffer(' + @spid + ')')

UPDATE #sp_who3
SET eventinfo = (SELECT EventInfo FROM #inputbuffer)
WHERE spid = @spid

FETCH NEXT FROM cur_dbccinputbuffer INTO @spid

END

CLOSE cur_dbccinputbuffer
DEALLOCATE cur_dbccinputbuffer

-- cursor End

IF @loginame IS NULL
BEGIN
SELECT *
FROM #sp_who3
ORDER BY spid
END
ELSE IF @loginame = 'ACTIVE'
BEGIN
SELECT *
FROM #sp_who3
ORDER BY spid
END
ELSE IF isnumeric(@loginame) = 1
BEGIN
SELECT *
FROM #sp_who3
WHERE spid = cast(@loginame as int)
END
RETURN 0
END



若要用在SQL 2005上,請將nvarchar(255)取代為nvarchar(max)即可

2009年1月18日 星期日

AS400如何透過DTS轉入SQL Server2000

剛好同事問有沒有文件,想說順便寫一下設定步驟好囉!

1.請確定在你執行的那台server上已裝好Client Access囉,如果你想在Client端也能用,那Client端也要裝!
2-1.裝好後我通常是先設定ODBC啦,再[開始][執行]那邊輸入odbcad32,這邊之後再設也行


2-2. 然後在[ODBC資料來源管理員]畫面的[系統資料來名稱]頁籤,按下[新增]
2-3.在[建立新資料來源]畫面,選取[iSeries Access ODBC Driver],按下[完成 ]

2-4.在[iSeries Access for Windows ODBC設定]畫面的[一般]頁籤,設定[資料來源名稱],名稱看你想設定什都可,與[系統]的ip位址,也就是AS400的位置2-5. 切換到[伺服器]頁籤,設定[SQL的預設檔案庫],也就是AS400的Library囉,如果有多個的話,是設在下面的[檔案庫清單],然後按下[確定],ODBC的設定就完成囉!
3.這邊我就假設你已在DTS裡拉好一個[其他連線] ,然後你就在[連線屬性]的設定畫面裡,在下方的[使用者/系統DSN]那各下拉選單,選取你剛設好的資料來源,然後再設定與AS400連線的使用者名稱與密碼,就可以按下[確定]囉,我剛在第2步也說,ODBC也是可以這時候再設的,按下[新增]就可以在設定其他的囉,步驟與第2步差不多
4.若你之前的設定都正確的話,當你拉一個[轉換資料工作]時,在[來源]的屬性設定頁籤裡,[資料表/檢視表]下拉選單是可以看到那些在AS400的table的喔

2009年1月16日 星期五

批次檔的執行條件處理IF

IF在批次檔中大概有3種格式,我配合我用過的例子作說明,如下:

1. IF [NOT] 參數==字串 command
參數如果等於指定的字串,則條件成立,就會運行命令
例子1:我有一個批次檔,每天排程執行,當遇到週日我想執行不一樣的命令, 內容要怎麼寫?


::取日期與星期幾
for /f "tokens=1,2" %%i in ('date /T') do set vard=%%i&& set vare=%%j
::判斷是否週日,如果是週日跳到另一段落
if %vare%==星期日 goto addsun
::下面執行非週日的命令
echo 執行非週日命令

exit
::下面執行週日的另令
:addsun
echo 執行週日命令


例子2:各位都知道windows排定的工作是可以細到每分鐘的執行一次的,那如果我排定一個批次檔是每天的九點開始執行,每小時執行一次,直到下午五點,批次檔會寫記錄到Log中,這樣排定,批次檔每隔一小時就執行一次,但是我想在這批次檔中作到第一次執行時,先把Log檔清空,怎麼作呢?


if %time:~0,2% EQU 9 echo. >c:\test.log
答案是利用時間囉,因為排程是時間是9點開始,那我判斷時間是9點才執行清檔就可以,簡單吧,系統時間%time%是20:29:11.04囉

2. IF [NOT] EXIST filename command

如果有指定的檔,則條件成立,就運行命令,通常用來測試檔案是否存在
例子:我把一個註冊表的機碼匯到暫存區的一個檔,那我希望在批次檔中判斷當此檔存在時,就無聲執行它,怎麼作?
if exist %temp%\addreg.reg regedit /s %temp%\addreg.reg
3. IF [NOT] ERRORLEVEL number command
DOS程式執行完都會傳回一個數字,稱為錯誤碼errorlevel或回傳碼,如果回傳碼等於指定的數字,則條件成立,就運行命令囉
例子:如果檔案複製成功,我希望LOG.txt就會顯示"成功複製檔案",否則就會顯示"檔案複製失敗"


XCOPY C:\AUTOEXEC.BAT D:\
IF ERRORLEVEL 1 ECHO 成功複製檔案 >c:\LOG.txt
IF ERRORLEVEL 0 ECHO 檔案複製失敗 >c:\LOG.txt
IF ERRORLEVEL 是用來測試它的上一個DOS命令的回傳值的,注意只是上一個命令的回傳值喔,而且回傳值必須依照從大到小次序順序判斷,否則會出錯喔。


2009年1月13日 星期二

自動刪除七日前的檔案

最近剛好需要,上網有找到例子,可是沒法直接用,會出錯,只好再參考指令碼存放庫的sample,改了後終於可以用了,分享給大家囉!

下面這個例子是會刪除在c:\Downloads下7天前所建立,然後副檔名為txt文字檔囉,請複製後存成vbs的檔案就可以了,也可以用在DTS裡的ActiveX Script喔

執行sp_helpdb發生錯誤

最近遇到一個問題,就是在Query Analyzer執行sp_helpdb出現下列錯誤

伺服器: 消息 515,級別 16,狀態 2,過程 sp_helpdb,行 53
無法將 NULL 值插入列 'owner',表 'tempdb.dbo.#spdbdesc___________________________________________________________________________________________________________00010000001F';該列不允許空值。INSERT 失敗。


然後執行第二次時又出現

伺服器: 消息 515,級別 16,狀態 2,過程 sp_helpdb,行 53
無法將 NULL 值插入列 '',表 '';該列不允許空值。INSERT 失敗。


當時想說,這不是系統內建的嗎?怎麼會出錯呢?
怪的是,若我用"sp_helpdb 資料庫名字"又沒問題
只好上網Goggle一下囉
原來是某個資料庫的擁有者遺失或不正確所造成

一一去查看資料庫的擁有者,還真的有資料庫擁有者那邊是空白的耶,真是見鬼了

解決辦法:執行sp_changedbowner 'sa'去指定擁有者囉

2009年1月11日 星期日

使用[查閱]轉換的注意事項

SQL Server 2005線上叢書說:"依預設,查閱轉換會將整個參考資料表放在記憶體的快取中,以提供最佳的效能。如果您未選取 [進階] 索引標籤上的任何選項,查閱轉換就會使用此預設行為。如果有記憶體限制,[進階] 索引標籤上的選項可讓您只設定部份快取。"

2009年1月10日 星期六

[OLE DB來源]請使用"SQL 命令"來取得資料



最近在參考一些SSIS效能調教的文章,有提到說在使用[OLE DB來源]時,資料存取模式使用[SQL 命令]的效能會比使用[資料表或檢視]來的好

2009年1月9日 星期五

[SQL server目的地]的逾時時間

這好像是個bug,逾時預設是30秒,如果不更改為0,也就是不限制時間的話,有時執行會遇到莫名的錯誤說,我更改為0後,就正常很多了,給各位參考一下

2009年1月8日 星期四

奇怪的CHECKSUM函數

最近剛好在研究SSIS,想說如何做到當資料有異動時去更新資料,上網查到一篇文章Using a checksum to determine if a row has changed,我才知道原來有CHECKSUM這個函數啊

這個函數有趣的地方是,它會針對你給的資料清單,清單可以是資料行,然後產生一組湊雜(hash)值,線上叢書這麼稱呼的啦,比如說
SELECT CHECKSUM('a1','adalf')
--256163607
SELECT CHECKSUM('al','adalf')
--1620787439
看到沒,如果給的值不相同,產生的湊雜值也不同
用這個值當索引,就可以當湊雜索引囉
用這個值當作比較,也可以用來判斷資料是否不一樣,不一樣就需要更新
那我就想到也許可以拿來當作unique index啊
如果原本索引欄位很長,透過這個轉變索引成數值欄位,效能應該會更好
問題是線上叢書竟然說
如果變更了運算式清單中的其中一個值,清單的總和檢查碼通常也會改變。不過,總和檢查碼也有可能不會變更。
哇哩勒,意思就是不保證唯一啦,還可能會重複,連當作比較都有問題
那這樣還可以拿來作什啊,真是不好用

2009年1月7日 星期三

AS400要怎樣才能轉入SQL Server 2005呢?(二)

先參考AS400要怎樣才能轉入SQL Server 2005呢?(一),了解一下,然後確認已經在Server上裝好Client Access 囉,我這邊指講資料來源是AS400時要怎麼設定喔,只針對SSIS的部分,如果你用的是SSMS的匯入匯出精靈,來源端的設定也大同小異啦,只是畫面長的不一樣而已囉

1.在[連接管理員]下方的空白處按右鍵,選擇[新增OLE DB連接]


2.在[設定OLE DB連接管理員]的設定畫面,按下[新增]


3.在[連接管理員]的設定畫面,在[提供者]旁的下拉選單


選擇IBMDA400的那個囉,然後按下[確定]

4. 然後在[伺服器名稱或檔名]那邊輸入AS400的ip,在使用者名稱及密碼那邊輸入連線到AS400用的帳號密碼囉,通常[允許儲存密碼]我會打勾,[初始資料庫目錄]不需設定,留空即可,很多人會誤以為這要填LIBRARY,LIBRARY是在後面才設定的,這跟設ODBC是不一樣的地方,然後按下[測試連接]




5.出現[連接測試成功]就表示OK了,然後按下[確定]


6. 確認[資料連接]出現新的設定,然後該設定的[資料連接屬性]是你剛設的資訊,再按下[確定]吧
7.然後[連接管理員]就會多一個你剛設的,在[控制流程]頁籤先拉一個[資料流程工作],在[資料流程]頁籤再拉一個[OLE DB來源],在[OLE DB來源]上滑鼠快點兩下


8.在[OLE DB來源編輯器]裡,[OLE DB連接管理員]選剛設好的那個, [資料存取模式]選[SQL 命令],[SQL命令文字]請輸入SQL陳述式囉,注意此處的SQL陳述式,需指定LIBRARY,而且要用LIBRARY.TABLE,不是LIBRARY/TABLE喔,像下圖那樣喔,"SELECT * FROM LIBRARY.TABLE"

8.如果SQL命令文字不正確,按下[預覽]或左邊的[資料行],是會跳出錯誤的視窗的
還好我有用過AS400兩年,像 "SQL0204: TEST in LBNFIL type *FILE not found."的錯誤,就是告訴你,在LBNFIL下並沒有TEST這個table囉,請檢查是LIBRARY打錯還是TABLE打錯囉


9.如果SQL命令文字正確,直接按下[資料行],就可以看到實際的資料行囉,此時就可以按下[確定]了,來源設定完成!

2009年1月6日 星期二

OLE DB命令似乎只能處理簡單的SQL陳述式

最近在使用OLE DB命令,這個元件的用處就是能夠以來源內的每筆資料列內容當作參數,對資料表執行Insert,Update,Delete的語法,有點像Cursor一樣可作單筆處理,但使用時發現似乎只能使用簡單的SQL陳述式,inner join 的我不知怎麼下,因為在SSMS裡執行正常啊,子查詢好像確定是不能用在這囉

比如說,我使用inner join

update CUACCP5_Master_fset FLINE = 30from
dbo.CUACCP5_Master_f as f1 inner join dbo.CUACCP5_Master_p as p1on (f1.idt_key =
p1.idt_key ) where p1.Key1= ?


就出現錯誤

描述:無法繫結多重部分(Multi-Part)識別碼"p1.Key1"
然後我改成子查詢

update CUACCP5_Master_f set FLINE = 30from CUACCP5_Master_f where
CUACCP5_Master_f.idt_key in(select idt_key from CUACCP5_Master_p where Key1 =
?)
就出現錯誤
描述:無法從具有 sub-select 查詢的 SQL 陳述式衍生參數資訊。

去微軟技術論壇發問,也只有一個前輩回答我,但也得不到解決辦法,後來我想到一個辦法了,就是我把那個inner join的寫到預存程序裡,然後在OLE DB命令去執行那個預存程序囉,好麻煩啊

2009年1月4日 星期日

AS400要怎樣才能轉入SQL Server 2005呢?(一)

最近接到個任務剛好有這個需要,在SQL 2000時代,需透過Client Access(IBM iSeries Access for Windows)去轉的,然後還要設定odbc,是很麻煩的,在SQL 2005呢?原本是藉由資料通轉入SQL Server的,因為用Client Access我們沒人會啊,後來問我們400的管理人員,才知道原來資料通也是透過Client Access去轉的,那表示我應該可以直接用Client Access去轉啊,不用透過資料通,效能應該會好點,因為原本透過資料通,光轉一百五十萬筆就得花1小時了,那我這次任務,得轉四千多萬筆,那不是得轉好多天啊!所以我得去研究這個我們目前沒人會的東東,皇天不付苦心人,上網搜尋好多天,終於實作出來了,四千多萬筆花不到6小時後,已經快很多吧!不過此篇我不先介紹步驟,下篇再介紹,我先介紹Client Access裡面所提供的三個OLE DB providers的差別,這我也找很久說,最後從IBM Redbooks裡面找到的,我直接把我認為的重點轉貼出來好了,如有人認為不妥,我再刪掉好囉

The V5R3 release of iSeries Access for Windows includes three OLE DB providers:



  1. New SQL-only provider (IBMDASQL) that supports SQL Commitment Control and MTS.


  2. New RLA-only provider (IBMDARLA) that supports true record blocking and forward-only cursors for record level access.


  3. The IBMDA400 provider, which supports SQL statements, record level access, remote command and program call, and data queues. It does not support Commitment Control for SQL commands, and does not support MTS.

    那紅皮書裡面還有講一些限制喔,各位可以參考參考

  另外也許有人會問IBMDA400與IBMDASQL使用上速度有何差別?我個人反覆實測傳輸223,167筆資料下,兩個速度差異不大,只差數秒間,差一秒有差嗎?我個人覺得沒差囉

2009年1月3日 星期六

自動重開機

一般情況要自動重開機很簡單,很多小工具可以達成,但是若server的桌面是在"鎖定"的狀態下,直接排程重開機的指令是沒有作用的喔,最好的方好是先排程"登出"的指令,然後再排程"重開機"的指令囉