如何使用 OracleDataReader 检索给定记录的所有字段?
Posted
技术标签:
【中文标题】如何使用 OracleDataReader 检索给定记录的所有字段?【英文标题】:How to retrieve all fields for a given record using OracleDataReader? 【发布时间】:2013-04-25 18:46:57 【问题描述】:我的问题类似于this one,是目前,我一直在使用这种方法,它一次只返回一个列值:
public string Select_File(string filename, string subdirectory, string envID)
Data_Access da = new Data_Access();
OracleConnection conn = da.openDB();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM EIP_Deployment_Files"
+ " WHERE Filename ='" + filename + "'"
+ " AND Subdirectory = '" + subdirectory + "'"
+ " AND Environment_ID = '" + envID + "'";
cmd.CommandType = CommandType.Text;
string x;
OracleDataReader dr = cmd.ExecuteReader();
if (dr.HasRows) // file exists in DB
dr.Read();
x = dr.GetString(2).ToString(); // return baseline filename (index 2)
else
x = "New File";
cmd.Dispose();
da.CloseDB(conn);
return x;
我确信这种方法远非完美,人们会很快指出这一点(我基本上是由我的主管给的,因为我之前没有任何 ASP.NET 经验)但我真的关心的是它的工作原理。我的问题是:如何修改它以返回给定记录的所有字段?
这些字段将是 VARCHAR2、CHAR 或 DATE 数据类型(如果有区别的话),其中一些值可能为空。我在想我可以将它们转换为字符串并将它们作为列表返回吗?
【问题讨论】:
注意:cmd.CommandText
容易受到注入攻击
【参考方案1】:
如果你想要这样的东西:
List<User> lstUser = new List<User>();
string sqlQuery = "Select * from User_T where User_Name='" + oUser.UserName + "' And Password='" +oUser.Password + "' AND IsActive='"+1+"' AND IsDelete='"+0+"'";
string connectionString = "Data Source=ORCL;User Id=ACCOUNTS;Password=ACCOUNTS";
using (DBManager dbManager = new DBManager(connectionString))
try
dbManager.Open();
OracleDataReader dataReader = dbManager.ExecuteDataReader(sqlQuery);
while (dataReader.Read())
oUser = new User();
oUser.Id = Convert.ToInt32(dataReader["ID"]);
oUser.CompanyId = Convert.ToInt32(dataReader["Company_ID"]);
oUser.BranchId = Convert.ToInt32(dataReader["Branch_ID"]);
oUser.UserName = Convert.ToString(dataReader["User_Name"]);
lstUser.Add(oUser);
dataReader.Close();
dataReader.Dispose();
catch
(Exception)
finally
dbManager.Close();
dbManager.Dispose();
【讨论】:
嗯,也许吧!我将不得不调查它tmw,但感谢您的回答 这是按名称读取每一列,这与读取所有列的名称不同。 注意:sqlQuery
容易受到注入攻击
正如@rdev5 所指出的,此代码示例存在严重的安全问题,并且代码未检查 DBNull,这将在调用 Convert.To... 方法时导致异常。 dbManager .Dispose 方法不需要在 finally 块中调用,因为它已经在 using 块中。【参考方案2】:
要从 DataReader 中当前行的列中读取所有数据,您可以简单地使用 GetValues(),然后从数组中提取值 - 它们将是数据库类型的对象。
Object[] values;
int numColumns = dr.GetValues(values); //after "reading" a row
for (int i = 0; i < numColumns; i++)
//read values[i]
MSDN - “对于大多数应用程序,GetValues 方法提供了一种有效的方法来检索所有列,而不是单独检索每一列。”
【讨论】:
对不起,我很困惑。 GetValues() 是否检索记录的每个字段的实际值? 是的。它填充您传入的对象数组,同时返回列数作为返回值。这是它的文档链接:msdn.microsoft.com/en-us/library/… 好吧,我不确定您想如何读取这些值,这就是伪代码的原因。您可以将 values[i](它将是一个 Object)读入任何您想要的内容,StringBuilder、数组、结构等等。【参考方案3】:很抱歉发布一个非常古老的问题的答案。由于没有一个答案是正确的(他们有安全问题或没有检查 DBNull),我决定发布自己的答案。
public async Task<StringBuilder> FetchFileDetailsAsync(string filename, string subdirectory, string envId)
var sb = new StringBuilder();
//TODO: Check the parameters
const string connectionString = "user id=userid;password=secret;data source=" +
"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.0.0.8)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xe)))";
const string selectQuery = "SELECT * FROM EIP_Deployment_Files"
+ " WHERE Filename = :filename"
+ " AND Subdirectory = :subdirectory"
+ " AND Environment_ID = :envID"
+ " AND rownum<=1";
using (var connection = new OracleConnection(connectionString))
using (var cmd = new OracleCommand(selectQuery, connection) BindByName = true, FetchSize = 1 /*As we are expecting only one record*/)
cmd.Parameters.Add(":filename", OracleDbType.Varchar2).Value = filename;
cmd.Parameters.Add(":subdirectory", OracleDbType.Varchar2).Value = subdirectory;
cmd.Parameters.Add(":envID", OracleDbType.Varchar2).Value = envId;
//TODO: Add Exception Handling
await connection.OpenAsync();
var dataReader = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection);
var rowValues = new object[dataReader.FieldCount];
if (dataReader.Read())
dataReader.GetValues(rowValues);
for (var keyValueCounter = 0; keyValueCounter < rowValues.Length; keyValueCounter++)
sb.AppendFormat("0:1", dataReader.GetName(keyValueCounter),
rowValues[keyValueCounter] is DBNull ? string.Empty : rowValues[keyValueCounter])
.AppendLine();
else
//No records found, do something here
dataReader.Close();
dataReader.Dispose();
return sb;
【讨论】:
以上是关于如何使用 OracleDataReader 检索给定记录的所有字段?的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中将 OracleDataReader 导出到 Excel
OracleDataReader reader.Read() 从第二个记录行开始读取行,跳过第一行记录
C# Oracle OracleDataReader.Read()