2009年12月26日 星期六
了解Email Headers所代表的意義
一般的郵件傳輸的過程至少經過4台電腦,怎麼說呢,當使用者發送郵件,會在使用者自己的電腦上產出訊息,然後訊息會先送到你指定寄件用的Mail Server(可能是你ISP用的或公司的),此時使用者的電腦已完成它的發送工作,但是Mail Server還沒完成他的工作,他會幫你找到收件者的Mail Server,跟她溝通然後將訊息傳送給她才算完成,這訊息會待在第二台Mail Server上,直到收件者讀取該訊息,將訊息下載到收件者的電腦後刪除,整個流程大概是這樣。
2009年12月22日 星期二
使用CDO.Messages來發信,未設定認證(smtpauthenticate)的奇怪現象
我平常在正式環境使用都是用遠端,然後有啟用基本認證,要輸入帳號密碼後才能寄,這樣幾乎不管到哪裡,程式都能寄信,到目前為止我還沒遇過有問題的,相關程式碼在 http://adalf0722.blogspot.com/2008/12/vbs.html
2009年12月20日 星期日
非sysadmin在SSMS中開啟Data Transformation Services的錯誤
SELECT 使用權限在物件 'sysdtspackages',資料庫 'msdb',擁有者 'dbo' 上被拒絕。 (Microsoft SQL Server, 錯誤: 229)
2009年11月10日 星期二
如何用sp_executesql將Select的值輸出
2009年10月9日 星期五
DTS的owner與owner_sid不一致的問題
上網查了一下發現可以用sp_reassign_dtspackageowner [@name =] 'name',[@id =] 'id',[@newloginname =] 'newloginname'來改變DTS的owner
2009年8月15日 星期六
2009年8月5日 星期三
msxml3.dll 錯誤 '800c000e'
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的影響
程式如下
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的影響
因為不明的原因造成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黃燈阻塞的解決辦法
2009年5月6日 星期三
交易記錄檔備份失敗
今天收到"資料庫維護計劃-交易記錄檔備份"竟然失敗的訊息,真是詭異,因為是第一次看到,更詭異的是看作業的錯誤訊息竟然看不出所以然,如下:
以下列使用者的身分執行: Domain\administrator。 sqlmaint.exe 失敗。 [SQLSTATE 42000] (錯誤 22029). 步驟失敗。
看那錯誤我誤以為那身分是不是帳密有改過, 問我們MIS確定是沒有的,只好上網查,原來真正錯誤訊息要去看維護計劃歷程記錄中失敗的項目,才找到原因,原來是我早上動到某個資料庫的復原模式的關係啊
2009年4月19日 星期日
DTS的工作順序也許不是你想的那樣
原本以為執行的順序是[4002SQL1(1)]跟[4002SQL2(3)]都執行成功了,才執行[SQL2TXT3(2)]的,結果不是,如下圖
竟然[SQL2TXT3(2)]比[4002SQL(3)]早執行,要是[SQL2TXT3(2)]的工作,其中有資料是要靠[4002SQL2(3)]來傳輸的,那不就會有問題了嗎?
早知道就不要偷懶,乖乖一個一個的分開設比較安全!
後來發現,應該是我成功的工作流程屬性沒特別設定優先順序造成的,我從沒特別去設它...@@...如下圖以至於[4002SQL1(1)]完就接著作[SQL2TXT3(2)],所以那我再加入另一各步驟進來
執行後,終於跟我想的一樣了!!
2009年4月18日 星期六
2009年4月1日 星期三
如何在 SQL Server 的執行個體之間傳送登入和密碼
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。
訊息 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
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無法更新
想裝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日 星期日
刪除七天前無效的連線
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日 星期四
2009年2月11日 星期三
JAVAMAIL範例2(不需認證的smtp)
< % @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)
< % @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進階用法
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語句的應用
可在命令列下"for /?"得到詳細資訊喔
0.基本應用(沒有啟用擴充命令)
就是手動去指定迴圈範圍,語句如下
例子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語句5:
c:\temp\test\a2.txt
c:\temp\test\f\a3.txt
c:\temp\bbb\a4.txt
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加強版
--只適用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],按下[完成 ]
3.這邊我就假設你已在DTS裡拉好一個[其他連線] ,然後你就在[連線屬性]的設定畫面裡,在下方的[使用者/系統DSN]那各下拉選單,選取你剛設好的資料來源,然後再設定與AS400連線的使用者名稱與密碼,就可以按下[確定]囉,我剛在第2步也說,ODBC也是可以這時候再設的,按下[新增]就可以在設定其他的囉,步驟與第2步差不多
4.若你之前的設定都正確的話,當你拉一個[轉換資料工作]時,在[來源]的屬性設定頁籤裡,[資料表/檢視表]下拉選單是可以看到那些在AS400的table的喔
2009年1月16日 星期五
批次檔的執行條件處理IF
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.reg3. IF [NOT] ERRORLEVEL number command
DOS程式執行完都會傳回一個數字,稱為錯誤碼errorlevel或回傳碼,如果回傳碼等於指定的數字,則條件成立,就運行命令囉
例子:如果檔案複製成功,我希望LOG.txt就會顯示"成功複製檔案",否則就會顯示"檔案複製失敗"
XCOPY C:\AUTOEXEC.BAT D:\IF ERRORLEVEL 是用來測試它的上一個DOS命令的回傳值的,注意只是上一個命令的回傳值喔,而且回傳值必須依照從大到小次序順序判斷,否則會出錯喔。
IF ERRORLEVEL 1 ECHO 成功複製檔案 >c:\LOG.txt
IF ERRORLEVEL 0 ECHO 檔案複製失敗 >c:\LOG.txt
2009年1月13日 星期二
自動刪除七日前的檔案
下面這個例子是會刪除在c:\Downloads下7天前所建立,然後副檔名為txt文字檔囉,請複製後存成vbs的檔案就可以了,也可以用在DTS裡的ActiveX Script喔
執行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日 星期日
使用[查閱]轉換的注意事項
2009年1月10日 星期六
2009年1月9日 星期五
2009年1月8日 星期四
奇怪的CHECKSUM函數
這個函數有趣的地方是,它會針對你給的資料清單,清單可以是資料行,然後產生一組湊雜(hash)值,線上叢書這麼稱呼的啦,比如說
SELECT CHECKSUM('a1','adalf')
--256163607
SELECT CHECKSUM('al','adalf')
--1620787439
看到沒,如果給的值不相同,產生的湊雜值也不同
用這個值當索引,就可以當湊雜索引囉
用這個值當作比較,也可以用來判斷資料是否不一樣,不一樣就需要更新
那我就想到也許可以拿來當作unique index啊
如果原本索引欄位很長,透過這個轉變索引成數值欄位,效能應該會更好
問題是線上叢書竟然說
如果變更了運算式清單中的其中一個值,清單的總和檢查碼通常也會改變。不過,總和檢查碼也有可能不會變更。
哇哩勒,意思就是不保證唯一啦,還可能會重複,連當作比較都有問題
那這樣還可以拿來作什啊,真是不好用
2009年1月7日 星期三
AS400要怎樣才能轉入SQL Server 2005呢?(二)
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打錯囉
2009年1月6日 星期二
OLE DB命令似乎只能處理簡單的SQL陳述式
比如說,我使用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:
- New SQL-only provider (IBMDASQL) that supports SQL Commitment Control and MTS.
- New RLA-only provider (IBMDARLA) that supports true record blocking and forward-only cursors for record level access.
- 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筆資料下,兩個速度差異不大,只差數秒間,差一秒有差嗎?我個人覺得沒差囉