Pages

2011年11月14日 星期一

HTTP3287: connection limit (XXXX) exceeded, closing socket

HTTP3287: connection limit (XXXX) exceeded, closing socket

發生的原因有:

1. Max. File Descriptor的設定小於實際的需求
Solve: 使用ulimit設定參數 
2. 使用Hot Deployed
Solve: 不要使用此部署方式,以免在效能有瓶頸的伺服器(太多On Demand需求)上發生此異常。 
3. Iplanet效能沒有設定好
Solve: 設定 ConnQueueSize的大小大於系統設定的Max. File Descriptor
參考:  
http://download.oracle.com/docs/cd/E19554-01/816-5690-10/816-5690-10.pdf

4. 系統某方面卡住了。
原因:  SQL Server Lock機制,導致系統連線Hang住,因此在程式中會產生LOCK的地方,一定要用rollback機制,以免系統被一個連線佔住,其他一直排隊進不去,連線數爆量,DBA終於找出問題了。

SQL語法中使用字串執行SQL語法


通常在資料庫的表格中有可能存在一些SQL的部分語法來讓程式存取使用。
但在寫Trigger或 Store Procedure時要如何使用這些字串?

正常來說直接使用exec sp_executesql @sqlcmd會出現下面的系統提示:
必須宣告純量變數@studentno。

因此需要做一些修改,可以從範例看出一些端倪:

假如我們的資料庫的分類表格中存在一個欄位儲存判斷式為

學生分數 between 80 and 90

之後我們可以宣告兩個變數與執行他們

declare @sqlcmd varchar(255)

declare @condition varchar(255)

declare @stundentno char(16)



set @sqlcmd = 'update 學生成績 set 分數分類 = ''A'' where studentno = @stundentno and '

select @condition =  condition  from 分類 // 取出分數介於80 ~ 90的狀況



 exec sp_executesql @sqlcmd + @condition ,N'@stundentno char(16) output',@stundentno output




2011年10月19日 星期三

Apache Tomcat 6 的記憶體配置 (效能調整)

Tomcat Server 預設可使用的記憶體為 128M,

若有大量網頁需求時, 會因記憶體太少, 而導致 Tomcat 當掉無法運作,

所以, 若要應付大量網頁的需求,需增加JVM的記憶體大小如下:



First Calculate the number of threads you can create

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

Example:

For Java 1.5 you will get the following results assuming that the OS reserves about 120MB:

1.5GB allocated to JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads

1.0GB allocated to JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads





Your Java Options Example: 

-Xms 512m
-Xmx 1024m
-Xss256k
-XX:MaxPermSize=256m
-XX:ReservedCodeCacheSize=128m 



另外一種方法,利用指令執行



於cmd下進入/bin
輸入 “tomcat6 //US//Tomcat6 –JvmMs 512 –jvmMx1024”
這兩個數值分別是最大與最小的heap size


如果是安裝是使用Windows服務帶起Tomcat,記得去註冊檔裡面修改參數

2011年10月18日 星期二

MS-SQL Server Log 檔清理方式


最近在刪除大筆資料時後發現,資料庫的LOG.LDF檔案會隨著刪除的比數增加,真是掰思不得其解。

於是上網尋找解決方案,總共有兩種。

1. 刪除法

第一步: 執行SQL語法,卸載資料庫:  
EXEC   sp_detach_db   @dbname   =   'MYDBNAME'

第二步: 刪除MYDBNAME_Log.LDF

第三步: 掛載SQL語法:
EXEC   sp_attach_single_file_db   @dbname   =   'MYDBNAME',   @physname   =   'C:\database\MYDBNAME_Data.MDF'

執行結果:
檔案啟動錯誤。實體檔案名稱 "C:\database\MYDBNAME_Log.LDF" 可能不正確。
已建立新記錄檔 'C:\database\MYDBNAME_log.LDF'。


2. 壓縮法

第一步: SP_HELPDB 可顯示資料庫資訊, 而資料庫的分頁名稱也會在裡面顯示出來
SP_HELPDB MYDBNAME


第二步: 備份資料庫, 但不備份記錄檔
BACKUP LOG MYDBNAME WITH NO_LOG

第三步: 備份記錄檔
BACKUP LOG db_name WITH TRUNCATE_ONLY

第四步: 使用 SHRINKFILE 把交易記錄檔縮小, 以 MB 為單位
DBCC SHRINKFILE(MYDBNAME_log, 100)

以上, 就可以看到磁碟空間變大, 記錄檔變小了 ~

2011年9月7日 星期三

使用Triple DES 加密字串

最近因為有需求,需要使用加密的方法來讓連線的帳號密碼用成亂碼來連線。
因此找到了使用 Tripple DES的方式加密字串。

1. 首先,先寄建立Decrypter與Encrypter
package security.crypto;

import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;

public classDecrypter {
	Cipher decipher;

	public Decrypter(SecretKey key) {
		try {
			decipher = Cipher.getInstance("DESede");
			decipher.init(Cipher.DECRYPT_MODE, key);

		} catch (javax.crypto.NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (java.security.NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (java.security.InvalidKeyException e) {
			e.printStackTrace();
		}
	}

	public String decrypt(String str) {
		try {
			byte[] decipher1 = new sun.misc.BASE64Decoder().decodeBuffer(str);

			byte[] decryptedBytes = decipher.doFinal(decipher1);

			return new String(decryptedBytes, "UTF8");
		} catch (javax.crypto.BadPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

package security.crypto;
import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;

import sun.misc.BASE64Encoder;

public class Encrypter {
	private Cipher encipher;

	public Encrypter(SecretKey key) {
		try {
			encipher = Cipher.getInstance("DESede");
			encipher.init(Cipher.ENCRYPT_MODE, key);

		} catch (javax.crypto.NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (java.security.NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (java.security.InvalidKeyException e) {
			e.printStackTrace();
		}
	}

	public String encrypt(String str) {
		try {
			byte[] encipher1 = str.getBytes("UTF8");

			byte[] encrpyedBytes = encipher.doFinal(encipher1);

			return new BASE64Encoder().encode(encrpyedBytes);
		} catch (javax.crypto.BadPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}
}

2. 接著建立使用該方法的連接介面
package security;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import wn.security.crypto.TripleDESDecrypter;
import wn.security.crypto.TripleDESEncrypter;

/**
 * 
 * @author asqqsa
 * 
 *         Here is a basic implementation of encrpytion and decryption using TripleDES.
 *         
 */

public class DES{

	public String getDecryptoString(String string) {
		String decrypted = null;
		try {
			Decrypter decrypter = new Decrypter(getKey());
			decrypted = decrypter.decrypt(string);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return decrypted;
	}
	
	public String getEncryptoString(String string) {
		String encrypted = null;
		try {
			Encrypter encrypter = new Encrypter(getKey());
			encrypted = encrypter.encrypt(string);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return encrypted;
	}

	private SecretKey getKey() {
 		// there are 32 chars
		String keyString ="1234567890abcdefghijklmnopqrstuv";
		byte[] keyB = new byte[24]; // a Triple DES key is a byte[24] array
		for (int i = 0; i < keyString.length() && i < keyB.length; i++) {
			keyB[i] = (byte) keyString.charAt(i);
		}
		SecretKey key = new SecretKeySpec(keyB, "DESede");
		return key;
	}
    /*****Random Generate Key Vlaue***
		public SecretKey getKey() {
		    try {
 		        return KeyGenerator.getInstance("DESede").generateKey();
 		    } catch (NoSuchAlgorithmException e) {
		        e.printStackTrace();
		    }
        	    return null;
		}
    **/
}
3. 建立JSP介面測試
<%@ page import="security.DES" %>
<%@ page contentType="text/html;charset=big5" %> 
<html>
<head></head>
<body>
<%
	DESCrypto des = new DESCrypto();
	String plain = null;
	String encrp = null;
	encrp = request.getParameter("plaintext");
	plain = request.getParameter("secrettext");
%>
<form method='post' name='des' action='Crypto.jsp'>
<table border = 1>
<tr><td colspan='2'>字串Triple DES 使用單一Key 加解密</td> </tr>
<tr>
<td>plaintext encrypto</td>
<td>secrettext decrypto</td>
</tr>
<tr>
<td><input name='plaintext' type='text'></inpute></td>
<td><input name='secrettext' type='text'></inpute></td>
</tr>
<tr>
<td><%= (encrp == null || encrp.equals(""))? " " : des.getEncryptoString(encrp)%></td>
<td><%= (plain == null || plain.equals(""))? " ": des.getDecryptoString(plain)%></td>
</tr>
<tr>
<td colspan='2'><input  type='submit' value='submit'></inpute></td>
</tr>
</table>
</form>
</body>
</html>

2011年8月13日 星期六

自動擷取憑證與Https頁面資料

在寫JSP使用Redirect的時候,如果是導向HTTPS頁面,也可能發生某些異常。
1. java.net.MalformedURLException: unknown protocol https
ANS: 使用的方法不是 HTTPS 的方式,將jce.jar與jsse.jar導入classpath,在使用https連線函式
2. 頁面停留過久
ANS: 就像打開IE一樣,會叫你點選接受憑證,這時用程式跑就自動停住了,居然不會timeout

<%@ page import="java.net.URL"%>
<%@ page import="java.net.URLEncoder"%>
<%@ page import="java.net.URLConnection"%>

<%@ page import="javax.net.ssl.HttpsURLConnection"%>
<%@ page import="javax.net.ssl.HostnameVerifier"%>
<%@ page import="javax.net.ssl.HttpsURLConnection"%>
<%@ page import="javax.net.ssl.SSLContext"%>
<%@ page import="javax.net.ssl.SSLSession"%>
<%@ page import="javax.net.ssl.TrustManager"%>
<%@ page import="javax.net.ssl.X509TrustManager"%>
<%@ page import="javax.security.cert.X509Certificate"%>
<%@ page import="javax.security.cert.CertificateException"%>
<%@ page import="java.security.SecureRandom"%>

/***
* more code
* skip
*/

/***********憑證擷取開始**************/
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
  public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
  }

  public void checkClientTrusted(java.security.cert.X509Certificate[] certs,String authType) {
  }

  public void checkServerTrusted(java.security.cert.X509Certificate[] certs,String authType) {
  }
} };

HostnameVerifier dummyHostnameVerifier = new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    return true;
  }
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(dummyHostnameVerifier);
/***********憑證擷取結束**************/

/***********擷取HTTPS頁面開始**************/
String httpsURL = "<https網址>"
try{
  url = new URL(httpsURL);

  Httpshurlconnection hurlc = (Httpshurlconnection) url.openConnection();
  hurlc.setRequestMethod("POST");
  InputStream inputStream = hurlc.getInputStream();
  LineNumberReader reader = new LineNumberReader(new InputStreamReader(inputStream));
  while (true) {
    tmp = reader.readLine();
    if (tmp == null)
      break;
    out.print(tmp);
  }
} catch (Exception e) {
  e.printStack();
}
/***********憑證擷取結束**************/

/***
* more code
* skip
*/

【CMD】建立以日期為主的資料夾

Windows XP & 2003   system
c:\> md d:\%Date:~0,4%%Date:~5,2%%Date:~8,2%

Windows 2k system
c:\> md d:\%Date:~4,4%%Date:~9,2%%Date:~12,2%



Microsoft JDBC 連接 URL 範例


在下列範例中,範例程式碼會在連接 URL 中設定各種連接屬性,然後呼叫 DriverManager 類別的 getConnection 方法,以傳回SQLServerConnection 物件。
接著,範例程式碼會使用 SQLServerConnection 物件的 createStatement 方法建立 SQLServerStatement 物件,然後呼叫 executeQuery方法來執行 SQL 陳述式。
最後,範例會使用從 executeQuery 方法傳回的 SQLServerResultSet 物件,重複執行 SQL 陳述式所傳回的結果。


import java.sql.*;

public class connectURL {

   public static void main(String[] args) {

      // Create a variable for the connection string.
      String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
         "databaseName=AdventureWorks;user=UserName;password=*****";

      // Declare the JDBC objects.
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;

      try {
         // Establish the connection.
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
         con = DriverManager.getConnection(connectionUrl);

         // Create and execute an SQL statement that returns some data.
         String SQL = "SELECT TOP 10 * FROM Person.Contact";
         stmt = con.createStatement();
         rs = stmt.executeQuery(SQL);

         // Iterate through the data in the result set and display it.
         while (rs.next()) {
            System.out.println(rs.getString(4) + " " + rs.getString(6));
         }
         rs.close();
         rs = null;
         stmt.close();
         stmt = null;
         con.close();
         con = null;
      }

      // Handle any errors that may have occurred.
      catch (Exception e) {
         e.printStackTrace();
      }
      finally {
         if (rs != null) try { rs.close(); } catch(Exception e) {}
         if (stmt != null) try { stmt.close(); } catch(Exception e) {}
         if (con != null) try { con.close(); } catch(Exception e) {}
      }
   }
}

Microsoft JDBC for MS SQL Server 系統需求



JDBC
for SQL Server 2000
JAR
msbase.jar

mssqlserver.jar

msutil.jar
jar
類別庫會提供 MSSQL2000 JDBC DRIVER 的支援。




JDBC
Driver支援 JRE 1.4,但連到SQL 2005 或 2008會出現異常。



JDBC
2.0 for SQL Server 2005
JAR
sqljdbc.jar sqljdbc.jar

類別庫會提供 JDBC 2.0 的支援。


sqljdbc.jar
類別庫需要使用 Java Runtime Environment (JRE) 5.0 版。 如果您在 JRE 6.0 上使用
sqljdbc.jar,將會在連接至資料庫時擲回例外狀況。


注意:

JDBC
Driver 不支援 JRE 1.4。 使用 JDBC Driver0 時,您必須將 JRE 1.4 升級為 JRE 5.0 或更新版本。
在某些情況下,您可能必須重新編譯應用程式,因為它可能與 JDK 5.0 或更新版本不相容。 如需詳細資訊,請參閱 Sun
Microsystems 網站上的文件。



JDBC
3.0 for SQL Server 2008
JAR
sqljdbc.jar sqljdbc.jar
類別庫會提供 JDBC 3.0 的支援。


sqljdbc.jar

類別庫需要使用 Java Runtime Environment (JRE) 5.0 版。 如果您在 JRE 6.0 上使用
sqljdbc.jar,將會在連接至資料庫時擲回例外狀況。


注意:

JDBC
Driver 不支援 JRE 1.4。 使用 JDBC Driver0 時,您必須將 JRE 1.4 升級為 JRE 5.0 或更新版本。
在某些情況下,您可能必須重新編譯應用程式,因為它可能與 JDK 5.0 或更新版本不相容。 如需詳細資訊,請參閱 Sun
Microsystems 網站上的文件。
sqljdbc4.jar sqljdbc4.jar
類別庫會提供 JDBC 4.0 的支援。 它包括
sqljdbc.jar

的所有功能以及新增的 JDBC 4.0 方法。


sqljdbc4.jar

類別庫需要使用 Java Runtime Environment (JRE) 6.0 版或更新版本。 在 JRE 1.4 或 5.0 上使用
sqljdbc4.jar將會擲回例外狀況。


意:


當您的應用程式必須在 JRE 6.0 上執行時,請使用 sqljdbc4.jar,即使應用程式並未使用 JDBC 4.0 功能也一樣。


以開發來說,當然是越新版功能越強。
但是如果需要可以跨所有SQL Server版本的JDBC驅動,可以安裝JTDS來符合需求。

目前幾乎都是用jtds來開發會比較方便,因為微軟一直出新的driver來相容新的SQL Server,
導致要一直更新JDBC,對穩定性及安全性來說,實在是有點風險阿。

static final long serialVersionUID用途

private static final long serialVersionUID = 1L 此變量有什麼用途?

一般在什麼情況下加入這樣的變量?它的值有什麼要求?
你可以這樣理解:
serialVersionUID用來表明類的不同版本間的兼容性。如果你修改了此類,要修改此值。否則以前用老版本的類序列化的類恢復時會出錯。為了在反序列化時,確保類版本的兼容性,最好在每個要序列化的類中加入private static final long serialVersionUID這個屬性,具體數值自己定義。
在警告上點左鍵就可以自動添加。當然也可以去掉警告。設置:Window-->Preferences-->Java,將serializable class without serialVersionUID的設置由warning改為Ignore。然後Eclipse會重新編譯程序,那些警告信息也就消失了。

serialVersionUID用來作為Java對象序列化中的版本標示之用;
如果一個序列化類沒有聲明這樣一個static final的產量,JVM會根據各種參數為這個類計算一個;
對於同樣一個類,不同版本的JDK可能會得出不同的serivalVersionUID;


The serializable class XXX does not declare a static final serialVersionUID field of type long
serialVersionUID作用:
序列化時為了保持版本的兼容性,即在版本升級時反序列化仍保持對象的唯一性。

你可以隨便寫一個,在Eclipse中它替你生成一個,有兩種生成方式:
一個是默認的1L,比如:private static final long serialVersionUID = 1L;
一個是根據類名、接口名、成員方法及屬性等來生成一個64位的哈希字段,比如:private static final long serialVersionUID = -8940196742313994740L;之類的。

當你一個類實現了Serializable接口,如果沒有定義serialVersionUID,Eclipse會提供這個提示功能告訴你去定義之。
在Eclipse中點擊類中warning的圖標一下,Eclipse就會自動給定兩種生成的方式,如上面所述。如果不想定義它,在Eclipse的設置中也可以把它關掉的,設置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems
將Serializable class without serialVersionUID的warning改成ignore即可。

如果你沒有考慮到兼容性問題時,就把它關掉,不過有這個功能是好的,只要任何類別實現了Serializable這個接口的話,如果沒有加入serialVersionUID,Eclipse都會給你warning提示,這個serialVersionUID為了讓該類別Serializable向後兼容。

如果你的類Serialized存到硬盤上面後,可是後來你卻更改了類別的field(增加或減少或改名),當你Deserialize時,就會出現Exception的,這樣就會造 ​​成不兼容性的問題。

但當serialVersionUID相同時,它就會將不一樣的field以type的預設值Deserialize,這個可以避開不兼容性的問題。

最後,不考慮兼容性的問題,我把這個warning改成ignore了。

SQL中的GETDATE() 轉換函式與產生結果

--Sql Server 中一个非常强大的日期格式化函数
Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827
Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM


--常用:
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16

2011年8月12日 星期五

重新命名資料庫名稱

要重命名資料庫中是非常普遍的使用
SQL Server 2000的用戶:
     EXEC sp_renameDB 'oldDB' , 'newDB'
SQL Server 2005支持向後兼容, 使用ALTER DATABASE修改名稱代替
  ALTER DATABASE MODIFY NAME


通常會出現錯誤:資料庫無法獨占鎖定來進行這個動作。


通用方法:
1. 卸載資料庫
2. 附載資料庫,這時候可以改資料庫名子!
3. 把之前的使用者的對應附加上去(可能會有孤兒問題)

2011年8月9日 星期二

SQL Server Studio Manager 抓取錯誤訊息

直接利用 PRINT使用下列函式,即可印出錯誤訊息。

USE AdventureWorks2008R2;
GO
-- Verify that the stored procedure does not already exist.
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL 
    DROP PROCEDURE usp_GetErrorInfo;
GO

-- Create procedure to retrieve error information.
CREATE PROCEDURE usp_GetErrorInfo
AS
SELECT
     ERROR_NUMBER() AS ErrorNumber
    ,ERROR_SEVERITY() AS ErrorSeverity
    ,ERROR_STATE() AS ErrorState
    ,ERROR_PROCEDURE() AS ErrorProcedure
    ,ERROR_LINE() AS ErrorLine
    ,ERROR_MESSAGE() AS ErrorMessage;
GO

BEGIN TRY
    -- Generate divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    -- Execute error retrieval routine.
    EXECUTE usp_GetErrorInfo;
END CATCH;

2011年8月8日 星期一

解決 MS-SQL Server 附加資料庫導致孤兒問題

附加資料庫後,資料庫的登入名稱變成空白,且無法使用新建的相同名稱指定登入。

可使用下面指令來指定登入的使用者。

USE database1
exec sp_change_users_login 'update_one','OneUser','LoginOneUser'