1、首先我们判断是否有列,一般是使用数据表来处理 :
DataTable dt = null ; dt.Columns.Contains("columnName");
2、利用异常处理:IndexOutOfRangeException
public static string getSQLDataReader(string sql,string column) { using (IDbConnection connect = new SqlConnection(constr)) { connect.Open(); using (IDbCommand cmd = connect.CreateCommand()) { cmd.CommandText = sql; string res = null; using (IDataReader dr = cmd.ExecuteReader()) { SqlDataReader sdr = dr as SqlDataReader; if (!sdr.HasRows) { throw new Exception("不存在数据!"); } try { sdr.GetOrdinal(column); } catch (IndexOutOfRangeException e) { return column + "指定列不存在!"; } while (dr.Read()) { res += " " + dr.GetValue(dr.GetOrdinal(column)); } } return res; // throw new Exception("未找到数据!"); } } }
3、思路将 SqlDataReader 转换陈 DataTable 来处理
①我对这个不熟悉,就犯了如下错误。
sdr.GetSchemaTable().Columns 并不是我要查询这个数据库的列,而是类似于系统数据库记录该表的相关信息,比如列名等存在对应记录里。
如果真要去查询应该这样子:sdr.GetSchemaTable().DefaultView.RowFilter = "ColumnName='" + column +"'";
注意这里的 ColumnName 就表示转换后的系统数据库列。查询的时候记得要要加单引号,类似 sql语句 where content = '内容'
② 关于 sdr.GetSchemaTable().DefaultView.RowFilter = "ColumnName='" + column +"'";
有个疑问,如果要 查询 这个过滤后的数据,是只要给属性赋值了就自动生成好了数据,还是需要我们在调用一个 执行 的方法才会生成过滤好的数据呢 ?
经过下面验证,其实给这个属性赋值下就已经执行了。
Console.WriteLine(sdr.GetSchemaTable().DefaultView.Count); // 返回的2 sdr.GetSchemaTable().DefaultView.RowFilter = "ColumnName='" + "name" +"'";//注意这个单引号 Console.WriteLine(sdr.GetSchemaTable().DefaultView.Count); //返回的1
③将 DataView对象转换成DataTable对象:
DataTable dt = sdr.GetSchemaTable().DefaultView.ToTable(); //表示转换过滤后的表
DataTable dt1 = sdr.GetSchemaTable().DefaultView.Table; //表示未过滤前的表,数据比较多。原始表
SqlDataReader sdr = dr as SqlDataReader; if (!sdr.GetSchemaTable().Columns.Contains(column)) //并不能判断是否包含该列,这是系统表 { foreach (var col in sdr.GetSchemaTable().Columns) { DataColumn dc = col as DataColumn; Console.WriteLine(dc.ColumnName); } return column + "指定列不存在!"; }