這次的老資料庫大概30萬條記錄,我第一次做,沒太考慮效率,這樣還是在朋友的協助下實現的,完成大概需要2個小時(cpu:賽揚3.06,記憶體:1.5G,環境:VS2005+SQL2000),哈哈!
經驗1:執行sql語句,不要笑。進來之前,我不知道如何執行多個sql語句,這也許是許多實習生的通病,要實現這個,可以建立多個sql語句,比如strSQL,strSQL1,strSQL2……strSQLi……,在多個SqlCommand對象中執行。
經驗2:選擇資料來源,這也許會令許多初次實踐者望而生畏,因為要訪問多個資料庫,可能不在一個伺服器上,這也太難實現了吧!其實呢,這些也確實難以實現,可是我們的巨人前輩們已經為我們鋪平路了,你所需要的只是跨出第一步,知道怎麼告訴資料庫去串連哪個資料庫,無論其在哪台機器上。那麼到底怎麼做呢?
是這樣的:定義字串:
string strSQLSource = "Data Source=ip地址或者伺服器名;Initial Catalog=你要訪問的機器上的資料庫名;User ID=使用者名稱一般是sa;Password=密碼";
Data Source=ip地址或者伺服器名,表明你只能訪問同一個域內的伺服器,至於如何訪問域外的伺服器,我還不知道,呵呵,但肯定能。
後面的就不用解釋了吧,呵呵……
當然,如果你想對多個伺服器進行操作,也可以像經驗1那樣,定義多個string類型的strSQLSource1,strSQLSource2,……,strSQLSourcei,等等。接著用SqlConnection定義的對象執行。
貼一點原始碼:
string strSQLSource, strSQL
strSQLSource = "Data Source=192.168.111.226;Initial Catalog=oldWXJS;User ID=sa;Password=";
strSQL = "select * from tmk";
SqlConnection sqlConn = new SqlConnection(strSQLSource);
SqlCommand sqlComm = new SqlCommand(strSQL, sqlConn);
sqlConn.Open();
經驗3:當程式還未訪問資料庫是就出錯了,你就按常規方法排錯,什麼是常規方法呢?就是機器幫你檢查的類型,命名,運算子等錯誤。這些比較容易排查。串連資料庫出錯時,這部分錯誤,初學者多犯忘了開啟資料庫或關閉資料庫的錯誤。這部分其實挺有規律的:常見的格式如下:
SqlConnection sqlConn2 = new SqlConnection(strSQLSource);
SqlCommand sqlComm2 = new SqlCommand(strSQL2, sqlConn2);
sqlConn2.Open();
int nFlag = Convert.ToInt32(sqlComm2.ExecuteScalar());
sqlConn2.Close();
另外還會常犯忘記轉換sqlComm2.ExecuteScalar()類型的錯誤,如上面int nFlag = Convert.ToInt32sqlComm2.ExecuteScalar());寫成int nFlag = sqlComm2.ExecuteScalar();
經驗4:怎樣利用斷點擷取資訊。當調試沒有錯誤後,你可能該迫不及待的點擊執行資料庫操作的按鈕了,這時對於初學者來說肯定會出現比較奇怪的錯誤。而我這次見到的是:截取伺服器: “訊息 170,層級 15,狀態 1,行 34
第 34 行: '新課標' 附近有語法錯誤。”“將截斷字串或位元據。語句已終止。”等錯誤,這些錯誤主要是資料庫方面的。比如說前者,是因為出現了特殊字元,那麼我是怎麼知道出現特殊字元了呢?就是利用斷點,或者利用VS的錯誤提示,先看看變黃的那部分錯誤提示,然後看看下面臨時變數框中的變數值,這個框通常和錯誤提示一起出現在主視窗的下部,下拉這個框的捲軸,你會看到各個變數出現錯誤是的值,一般對應sql語句的框條會在其右方出現下三角,你右擊該三角,會出現三個可選項,選擇一項你就可以查看當前的sql語句,如果你看不懂,就到sql查詢分析器裡好好琢磨,看看到底是哪裡出錯,結果也許你改變一下sql語句中的某個字串中的字元,運行就通過了!這就是出現特殊字元了。後者的錯誤通常是由於你在資料庫中定義了char型的欄位,而老庫中要加入該欄位的資料長度超出了該欄位的長度。那你就改成nvarchar或varcar或加長char的長度吧。
經驗5:怎麼寫過濾函數?像這樣:
public string FilterString(string FilteringString)
{
string Str_FilteringString;
//變數初始化
Str_FilteringString = FilteringString;
//過濾SQL的關鍵字符串
Str_FilteringString = Str_FilteringString.Replace(";", ";");
Str_FilteringString = Str_FilteringString.Replace("'", "‘");
Str_FilteringString = Str_FilteringString.Replace("-", "");
Str_FilteringString = Str_FilteringString.Replace(":", ":");
return Str_FilteringString;
}
Replace("'", "‘")表示用‘代替你從老庫中讀出來的字串中的'。
怎麼用呢?像這樣:
strTflh = FilterString(DR["tflh"].ToString().Trim());
strTtm = FilterString(DR["ttm"].ToString().Trim());
strTzz = FilterString(DR["tzz"].ToString().Trim());
經驗6:為進度條設定最大值!
像這樣:
strSQL1 = "select count(*) from tmk";
SqlConnection sqlConnCount = new SqlConnection(strSQLSource);
SqlCommand sqlCommCount = new SqlCommand(strSQL1,sqlConnCount);
sqlConnCount.Open();
int count =Convert.ToInt32(sqlCommCount.ExecuteScalar());
progressUpdate.Maximum = count;
progressUpdate為進度條對象。
要用sqlCommCount.ExecuteScalar()呀,不要用sqlCommCount.ExecuteNonQuery(),因為:
ExecuteScalar:執行查詢,並返回查詢所返回的結果集中第一行的第一列。查詢資料庫表的行數,並返回忽略額外的列或行。
ExecuteNonQuery主要是用來執行更新和刪除,並不返回任何值。實際上是對上述操作成功與否的標誌返回。
先總結這些吧,頭兒回來了!接著做多線程吧
貼一下完整的代碼吧!大家可以共用!呵呵
private void btnUpdate_Click(object sender, EventArgs e)
{
string strTflh,strTtm,strTzz,strTwxly,strTcbs,strTjh,strTys,strTch,strTwxlx,strExchange,strTwz,strTUser,strTtm2,strTflh2,strTflh3,strTflh4,strTkeyword1,strTkeyword2,strTkeyword3,strTkeyword4;
int strClicks, strRecord;
DateTime DT_InDate = System.DateTime.Now;
string strSQLSource, strSQL,strSQL1,strSQL2, strSQL3;
strTflh=strTtm=strTzz=strTwxly=strTcbs=strTjh=strTys=strTch=strTwxlx=strExchange=strTwz=strTUser=strTtm2=strTflh2=strTflh3=strTflh4=strTkeyword1=strTkeyword2=strTkeyword3=strTkeyword4="";
strClicks = strRecord = 0;
strSQLSource = "Data Source=192.0.0.0;Initial Catalog=oldWXJS;User ID=sa;Password=";
strSQL = "select * from tmk";
SqlConnection sqlConn = new SqlConnection(strSQLSource);
SqlCommand sqlComm = new SqlCommand(strSQL, sqlConn);
sqlConn.Open();
//返回老資料庫資料的行數
strSQL1 = "select count(*) from tmk";
SqlConnection sqlConnCount = new SqlConnection(strSQLSource);
SqlCommand sqlCommCount = new SqlCommand(strSQL1,sqlConnCount);
sqlConnCount.Open();
int count =Convert.ToInt32(sqlCommCount.ExecuteScalar());
progressUpdate.Maximum = count;
System.Data.SqlClient.SqlDataReader DR = sqlComm.ExecuteReader();
progressUpdate.Visible = true;
if (DR != null)
{
while (DR.Read())
{
progressUpdate.Minimum = 0;
strRecord = Convert.ToInt32(DR.GetInt32(DR.GetOrdinal("record")));
strTflh = FilterString(DR["tflh"].ToString().Trim());
strTtm = FilterString(DR["ttm"].ToString().Trim());
strTzz = FilterString(DR["tzz"].ToString().Trim());
strTwxly = FilterString(DR["twxly"].ToString().Trim());
strTcbs = FilterString(DR["tcbs"].ToString().Trim());
strTjh = FilterString(DR["tjh"].ToString().Trim());
strTch = FilterString(DR["tch"].ToString().Trim());
strTys = FilterString(DR["tys"].ToString().Trim());
strTwxlx = FilterString(DR["twxlx"].ToString().Trim());
DT_InDate = DR.GetDateTime(DR.GetOrdinal("indate"));
strExchange = FilterString(DR["exchange"].ToString().Trim());
strTwz = FilterString(DR["twz"].ToString().Trim());
strSQL2 = "select count(*) as Number from test1 where record='" + strRecord + "' and tflh='" + strTflh + "' and ttm='" + strTtm + "' and tzz='" + strTzz + "' and twxly='" + strTwxly + "' and tcbs='" + strTcbs + "' and tjh='" + strTjh + "' and tch='" + strTch + "' and tys='" + strTys + "' and twxlx='" + strTwxlx + "' and indate='" + DT_InDate + "' and exchange='" + strExchange + "' and twz='" + strTwz + "'";
SqlConnection sqlConn2 = new SqlConnection(strSQLSource);
SqlCommand sqlComm2 = new SqlCommand(strSQL2, sqlConn2);
sqlConn2.Open();
int nFlag = Convert.ToInt32(sqlComm2.ExecuteScalar());
sqlConn2.Close();
if (nFlag < 0)
{
//查詢過程出錯,用MessageBox.Show()方法提示錯誤,
return; //出錯就跳出,不繼續往下迴圈
}
else if (nFlag == 0)
{
strSQL3 = "insert into test1 values('" + strRecord + "','" + strTflh + "','" + strTtm + "','" + strTzz + "','" + strTwxly + "','" + strTcbs + "','" + strTjh + "','" + strTch + "','" + strTys + "','" + strTwxlx + "','" + DT_InDate + "','" + strExchange + "','" + strTwz + "','" + strTUser + "','" + strClicks + "','" + strTtm2 + "','" + strTflh2 + "','" + strTflh3 + "','" + strTflh4 + "','" + strTkeyword1 + "','" + strTkeyword2 + "','" + strTkeyword3 + "','" + strTkeyword4 + "')";
SqlConnection sqlConn3 = new SqlConnection(strSQLSource);
SqlCommand sqlComm3 = new SqlCommand(strSQL3, sqlConn3);
sqlConn3.Open();
int nFlag2 = sqlComm3.ExecuteNonQuery();
sqlConn3.Close();
if (nFlag2 != 1)
{
//提示插入出錯,用MessageBox.Show()方法
return; //出錯就跳出,不繼續往下迴圈
}
progressUpdate.Value += 1;
}
}
progressUpdate.Visible = false;
MessageBox.Show(this,"更新完成!");
}
else
{
MessageBox.Show(this,"抱歉!您要添加的資料為空白!");
}
}