-1

我有代码可以在不存在的情况下创建一个表并添加所有必要的列,但是对于用户拥有旧版本表的情况,它会添加一些新的

列。然而,当第二个条件为真并且添加列的 DDL 运行时,我得到,“列 ID 在规范中出现了不止一次”

这是代码以及用于确定表和列是否存在的辅助函数:

    bool tableExists = dbconn.isValidTable(tablename) != -1;
    if (!tableExists) 
    {
        ddl = "CREATE TABLE Bla (. . . salvationID nvarchar(19), salvation float, discount float)";
        dbconn.DBCommand(ddl, false);
    }
    else // (the table does exist) 
    {
        if(!dbconn.isValidField(tablename,"redemptionID"))
        {
            ddl = string.Format("ALTER TABLE {0} ADD redemptionID nvarchar(19) ", tablename);
            dbconn.DBCommand(ddl,false);
            . . .

        public int isValidTable(string tableName)
        {
            int validTable = -1;
            string tblQuery = string.Format("SELECT COUNT(*) FROM {0}", tableName);
            checkConnection();
            try
            {
                SqlCeCommand cmd = objCon.CreateCommand();
                cmd.CommandText = tblQuery;
                object objcnt = cmd.ExecuteScalar();
                validTable = Int32.Parse(objcnt.ToString());
            }
            catch
            {
                validTable = -1;
            }
            return validTable;
        }

//This has been beautified/elegantized thanks to p.s.w.g at http://stackoverflow.com/questions/15693639/how-can-i-determine-whether-a-column-exists-in-a-sql-server-ce-table-with-c
        public bool isValidField(string tableName, string columnName)
        {
            bool retVal;
            string tblQuery = "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND 

COLUMN_NAME = @columnName";
            checkConnection();
            try
            {
                SqlCeCommand cmd = objCon.CreateCommand();
                cmd.CommandText = tblQuery;
                SqlCeParameter tblNameParam = new SqlCeParameter("@tableName", SqlDbType.NVarChar, 128);
                tblNameParam.Value = tableName;
                cmd.Parameters.Add(tblNameParam);
                SqlCeParameter colNameParam = new SqlCeParameter("@columnName", SqlDbType.NVarChar, 128);
                colNameParam.Value = tableName;
                cmd.Parameters.Add(colNameParam);
                object objvalid = cmd.ExecuteScalar();
                retVal = !Convert.IsDBNull(objvalid);
            }
            catch
            {
                retVal = false; 
            }
            return retVal;
        }
4

2 回答 2

1

尝试检查DBNull.Value.

try
{
  SqlCeCommand cmd = objCon.CreateCommand();
  cmd.CommandText = tblQuery;
  object objcnt = cmd.ExecuteScalar();
  if ((objcnt != null) && (objcnt != DBNull.Value)) {
    validTable = Int32.Parse(objcnt.ToString());
  } else {
    MessageBox.Show("NULL returned from CreateCommand. Remove this line.");
  }
}
catch
于 2013-03-29T21:09:10.033 回答
1

我怀疑正在发生的事情isValidField()是抛出一个异常,而你的捕获只是在说明该字段不存在时吞下它......当它可能存在时。

我强烈建议您不要只是吞下它,而是实际显示该消息,以便您知道发生了什么。

例如:

public bool isValidField(string tableName, string columnName)
{
    bool retVal;
    string tblQuery = "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName";
    checkConnection();
    try
    {
        SqlCeCommand cmd = objCon.CreateCommand();
        cmd.CommandText = tblQuery;
        SqlCeParameter tblNameParam = new SqlCeParameter("@tableName", SqlDbType.NVarChar, 128);
        tblNameParam.Value = tableName;
        cmd.Parameters.Add(tblNameParam);
        SqlCeParameter colNameParam = new SqlCeParameter("@columnName", SqlDbType.NVarChar, 128);
        colNameParam.Value = tableName;
        cmd.Parameters.Add(colNameParam);
        object objvalid = cmd.ExecuteScalar();
        retVal = !Convert.IsDBNull(objvalid);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
        retVal = false; // <-- wrong answer
    }
    return retVal;
}

此外,该函数不应该是布尔值。你有3个条件:1.存在;2.不存在;3. 发生错误。

如果发生错误,您不希望后面的方法认为它找不到它。另外,我会对您验证表存在的地方做同样的事情。

于 2013-03-29T21:26:53.463 回答