2013-04-01 22 views
0

這SQLCE代碼看起來非常奇怪,我說:我應該重構一下嗎?還是我的混亂導致謹慎?

cmd.CommandText = "INSERT INTO departments (account_id, name) VALUES (?, ?)"; 
foreach(DataTable tab in dset.Tables) 
{ 
    if (tab.TableName == "Departments") 
    { 
     foreach(DataRow row in tab.Rows) 
     { 
      Department Dept = new Department(); 
      if (!ret) 
       ret = true; 
      foreach(DataColumn column in tab.Columns) 
      { 

       if (column.ColumnName == "AccountID") 
       { 
        Dept.AccountID = (string) row[column]; 
       } 
       else if (column.ColumnName == "Name") 
       { 
        if (!row.IsNull(column)) 
         Dept.AccountName = (string) row[column]; 
        else 
         Dept.AccountName = ""; 
       } 
      } 
      List.List.Add(Dept); 
      . . . 
      dSQL = "INSERT INTO departments (account_id, name) VALUES ('" + Dept.AccountID + "','" + Dept.AccountName +"')"; 

      if (!First) 
      { 
       cmd.Parameters[0].Value = Dept.AccountID; 
       cmd.Parameters[1].Value = Dept.AccountName; 
      } 

      if (First) 
      { 
       cmd.Parameters.Add("@account_id",Dept.AccountID); 
       cmd.Parameters.Add("name",Dept.AccountName); 
       cmd.Prepare(); 
       First = false; 
      } 

      if (frmCentral.CancelFetchInvDataInProgress) 
      { 
       ret = false; 
       return ret; 
      } 

      try 
      { 
       dbconn.DBCommand(cmd, dSQL, true); 
      } 
      . . . 

    public void DBCommand(SqlCeCommand cmd, string dynSQL, bool Silent) 
    { 
     SqlCeTransaction trans = GetConnection().BeginTransaction(); 
     cmd.Transaction = trans; 
     try 
     { 
      cmd.ExecuteNonQuery(); 
      trans.Commit(); 
     } 
     catch (Exception ex) 
     { 
      try 
      { 
       trans.Rollback(); 
      } 
      catch (SqlCeException) 
      { 
       // Handle possible exception here 
      } 
      MessageBox.Show("DBCommand Except 2"); // This one I haven't seen... 
      WriteDBCommandException(dynSQL, ex, Silent); 
     } 
    } 

我的問題是: 「?」

1)宜真的被用於cmd.CommandText的賦值,還是應該使用「@」來代替?

2)其中的 「cmd.Parameters.Add()」 S(ACCOUNT_ID的)使用 「@」 和其他(名稱)不。哪種方式是對的,還是「@」可選?

3)我不能爲什麼的DBCommand()被寫成它是正面還是反面 - 如果有一個例外,最終有兩個參數僅用於... ???

我很想從根本上重構這個代碼,因爲它似乎很離奇,但因爲我真的不明白,這可能是一個災難......

+1

這是SQL Server ..?如果是這樣的話,爲什麼不在插入命令時使用'@'符號,而使用'?'就像Access所期望的那樣。我會重構那些代碼以實現使用/使用.Parameters.AddWithValue()方法。 。我甚至會在你嘗試添加參數的地方將代碼封裝在try {} catch {}中。''''等同於'@',但看起來像DataAdapter樣式編碼我可能會被誤認爲.. – MethodMan

+0

我會重構它的一些存儲過程,並與數據調用。 – Romoku

+1

如果代碼有效,那麼最好在http://codereview.stackexchange.com/上詢問。 –

回答

0

?參數是老年人訪問句法。

我的猜測是這是一個Access數據庫,但有人在某些時候將其轉換爲SQL CE。

一般情況下,SQL明白?參數,但最好只改變,而你在那裏,以便它更清楚。

我仍然在努力使頭所有這些變量&尾巴。如果我把它整理出來,我會發布可編譯的(sp?)代碼。

編輯:我不得不把它放到一個方法中,並計算出所有的RED錯誤,以確保我沒有給你一些無法編譯的東西。

我通過它你的DataSet像這樣,有很多的評論說:

private bool StrangeSqlCeCode(DataSet dset) { 
    const string ACCOUNT_ID = "AccountID"; 
    const string DEPARTMENTS = "Departments"; 
    const string NAME = "Name"; 
    const string SQL_TEXT = "INSERT INTO departments (account_id, name) VALUES (@account_id, @name)"; 
    bool ret = false; 
    //bool First = false; (we don't need this anymore, because we initialize the SqlCeCommand correctly up front) 
    using (SqlCeCommand cmd = new SqlCeCommand(SQL_TEXT)) { 
    // Be sure to set this to the data type of the database and size field 
    cmd.Parameters.Add("@account_id", SqlDbType.NVarChar, 100); 
    cmd.Parameters.Add("@name", SqlDbType.NVarChar, 100); 
    if (-1 < dset.Tables.IndexOf(DEPARTMENTS)) { 
     DataTable tab = dset.Tables[DEPARTMENTS]; 
     foreach (DataRow row in tab.Rows) { 
     // Check this much earlier. No need in doing all the rest if a Cancel has been requested 
     if (!frmCentral.CancelFetchInvDataInProgress) { 
      Department Dept = new Department(); 
      if (!ret) 
      ret = true; 
      // Wow! Long way about getting the data below: 
      //foreach (DataColumn column in tab.Columns) { 
      // if (column.ColumnName == "AccountID") { 
      // Dept.AccountID = (string)row[column]; 
      // } else if (column.ColumnName == "Name") { 
      // Dept.AccountName = !row.IsNull(column) ? row[column].ToString() : String.Empty; 
      // } 
      //} 
      if (-1 < tab.Columns.IndexOf(ACCOUNT_ID)) { 
      Dept.AccountID = row[ACCOUNT_ID].ToString(); 
      } 
      if (-1 < tab.Columns.IndexOf(NAME)) { 
      Dept.AccountName = row[NAME].ToString(); 
      } 
      List.List.Add(Dept); 
      // This statement below is logically the same as cmd.CommandText, so just don't use it 
      //string dSQL = "INSERT INTO departments (account_id, name) VALUES ('" + Dept.AccountID + "','" + Dept.AccountName + "')"; 
      cmd.Parameters["@account_id"].Value = Dept.AccountID; 
      cmd.Parameters["@name"].Value = Dept.AccountName; 
      cmd.Prepare(); // I really don't ever use this. Is it necessary? Perhaps. 
      // This whole routine below is already in a Try/Catch, so this one isn't necessary 
      //try { 
      dbconn.DBCommand(cmd, true); 
      //} catch { 
      //} 
     } else { 
      ret = false; 
      return ret; 
     } 
     } 
    } 
    } 
    return ret; 
} 

我寫了你的DBCommand方法的重載與遺留代碼的工作:

public void DBCommand(SqlCeCommand cmd, string dynSQL, bool Silent) { 
    cmd.CommandText = dynSQL; 
    DBCommand(cmd, Silent); 
} 

public void DBCommand(SqlCeCommand cmd, bool Silent) { 
    string dynSQL = cmd.CommandText; 
    SqlCeTransaction trans = GetConnection().BeginTransaction(); 
    cmd.Transaction = trans; 
    try { 
    cmd.ExecuteNonQuery(); 
    trans.Commit(); 
    } catch (Exception ex) { 
    try { 
     trans.Rollback(); // I was under the impression you never needed to call this. 
     // If Commit is never called, the transaction is automatically rolled back. 
    } catch (SqlCeException) { 
     // Handle possible exception here 
    } 
    MessageBox.Show("DBCommand Except 2"); // This one I haven't seen... 
    //WriteDBCommandException(dynSQL, ex, Silent); 
    } 
} 
+0

我看到(+1)和(-1)的投票。像往常一樣,沒有人會承認他們的倒退或說他們爲什麼downvoted。 – jp2code

+1

這可能是貓王的幽靈,因爲 - 我永遠不會被抓到兔子。 –

1

我相當確定這篇文章將回答您的一些問題:

http://msdn.microsoft.com/en-us/library/yy6y35y8.aspx

第二張圖解釋了命名參數和位置參數(在OleDb和ODBC中使用)之間的區別。

我相信在這種情況下,被使用,@是可選的,但我不確定這一點。如果它的工作,我會說這是事實。

DBCommand中的東西似乎只是出於記錄目的。如果執行失敗,它會嘗試執行回滾,然後使用sql命令(在dynSQL中)記錄異常。

+0

有些東西不起作用,我不知道這是否是問題。我得到,「解析查詢時出錯」,但我不知道發生了什麼。掐一個「你爲什麼不穿過它」的迴應:我不能。這是一款具有非常有限的工具和調試功能的古老技術應用程序(VS 2003,.NET 1.1)。 –

+0

那麼我認爲加上@是謹慎的。這顯然是我所能看到的規範。什麼是後端數據庫? – Pete

+0

手持設備上的Sql Server CE。 –

相關問題