in debugging my wcf call its skipping the while loop and not reading the internal data. I've been bouncing through SO and msdn for help and nothing seems to stand out. Anyone have any clues as to what I'm missing or doing to cause this loop to not iterate through?
Solution: this was a DB problem, once I updated the Oracle DB values the query ran in SQL developer and debugging is working in VS2010.
Thanks
using (connection)
{
try {
connection.ConnectionString = connString;
OracleCommand command = new OracleCommand(sqlString, connection);
connection.Open();
OracleDataReader reader = command.ExecuteReader();
while (reader.Read()) {
td.TNAME = reader.IsDBNull(0) ? " " : reader.GetValue(0).ToString();
td.TASK = reader.IsDBNull(1) ? " " : reader.GetValue(1).ToString();
td.STATUS = reader.IsDBNull(2) ? " " : reader.GetValue(2).ToString();
td.COMPLETE = reader.IsDBNull(3) ? " " : reader.GetValue(3).ToString();
td.PRIORITY = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader.GetValue(4));
tl.Add(td);
}
//while (reader.NextResult());
reader.Close();
} catch (Exception ex) {
myErr = ex.Message;
}
}
return tl;
If you're actually getting to the while statement without execptions, then the obvious answer is that your datareader has no data. Try examining the value of reader.HasRows before the while loop. I imagine it will be false. Does your sql statement actually return data in SQL Developer?
There are two possible reasons for the loop to not execute:
There is an exception from the code that precedes the loop.
reader.Read() doesn't return any data.
Of course, if your loop never executes then there is no data returned from the query, but I see another problem in your code. The variable td is never re-initialized and in every loop you add to the list the same variable updated with the values extracted from the current loop values.
So you end with the value of the last loop in your tl (whatever is it)
I think you should write
while (reader.Read())
{
td = new YourTDClass(); // Create a new instance of an element of td class
td.TNAME = reader.IsDBNull(0) ? " " : reader.GetValue(0).ToString();
td.TASK = reader.IsDBNull(1) ? " " : reader.GetValue(1).ToString();
td.STATUS = reader.IsDBNull(2) ? " " : reader.GetValue(2).ToString();
td.COMPLETE = reader.IsDBNull(3) ? " " : reader.GetValue(3).ToString();
td.PRIORITY = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader.GetValue(4));
tl.Add(td);
}
I think you should write more easily:
var list = new List<dynamic>();
while(dr.Read())
{
var value = new YourClass {
propClassString = dr.GetString(0), //for string
propClassInt = dr.GetInt32(1), //for int
propClassDateTime = dr.GetDateTime(2) //for datetime
};
list.Add(value);
}
return list;
Related
I have the code
while (reader.Read())
{
if (reader[incrementer]!=DBNull.Value){
string playerToInform = reader.GetString(incrementer).ToString();
string informClientMessage = "ULG=" + clientIP + ","; //User Left Game
byte[] informClientsMessage = new byte[informClientMessage.Length];
informClientsMessage = Encoding.ASCII.GetBytes(informClientMessage);
playerEndPoint = new IPEndPoint(IPAddress.Parse(playerToInform), 8001);
clientSocket.SendTo(informClientsMessage, playerEndPoint);
}
incrementer++;
}
which after debugging my code i see contains 4 entries. However only the first result is ever read from the reader. After the first iteration to find if the result returned is null or not the loop starts again and immediately finishes even though there are three more rows to read.
Any ideas as to why this may be occuring would be apprechiated.
edit - this is the reader i used
OleDbDataReader reader = dBConn.DataSelect("SELECT player1_IP, player2_IP, player3_IP, player4_IP FROM running_games WHERE game_name = '" + gameName + "'", updateGameList);
The indexer of DbDataReader (DataReader is something else) or a database specific subclass, returns the value of the specified (by index or name).
While DbDataReader.Read() moves to the next row.
If you want to apply the same logic to multiple columns you need to loop over the columns, and the rows:
while (db.Read()) {
for (var colIdx = 0; colIdx < columnCount. ++colIdx) {
if (!db.IsDbNll(colIdx)) {
string value = db.GetString(colIdx);
// Process value
}
}
}
You're incrementing "incrementer" as if that was the row number, but a DataReader holds only one row per Read() and the indexing is for the field number.
Use this:
while (reader.Read())
{
for(int colNum = 0; colNum < 4; colNum++)
{
if (reader[colNum]!=DBNull.Value)
{
string playerToInform = reader.GetString(colNum).ToString();
string informClientMessage = "ULG=" + clientIP + ","; //User Left Game
byte[] informClientsMessage = new byte[informClientMessage.Length];
informClientsMessage = Encoding.ASCII.GetBytes(informClientMessage);
playerEndPoint = new IPEndPoint(IPAddress.Parse(playerToInform), 8001);
clientSocket.SendTo(informClientsMessage, playerEndPoint);
}
}
}
Incrementer is unnecessary. reader.Read() advances to next record and returns false if there are no more rows.
Check documentation on msdn
I am doing a bulk upload through C#.
It is not a complicated piece of code, but struggling as although the code runs successfully I am not seeing anything on the Database end when I run a query against the destination table.
The table is
[awsbillingdetailed_w_res_tags]
public static string BulkUpload(DataTable dt, string tableName, string connectionString)
{
string code = "";
//just resizing datatable so that it makes it smaller for testing. Only 5 rows.
dt = ReduceDataTableSize(dt, 5);
dt.TableName = tableName;
string constr = connectionString;
try
{
using (SqlConnection connection = new SqlConnection(constr))
{
connection.Open();
//CreatingTranscationsothatitcanrollbackifgotanyerrorwhileuploading
SqlTransaction trans = connection.BeginTransaction();
//Start bulkCopy
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers,
trans))
{
//Fix up default values
if(dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i]["InvoiceId"] = dt.Rows[i]["InvoiceId"].ToString().Replace("\"", "");
dt.Rows[i]["PayerAccountId"] = dt.Rows[i]["PayerAccountId"].ToString().Replace("\"", "");
dt.Rows[i]["LinkedAccountId"] = dt.Rows[i]["LinkedAccountId"].ToString().Replace("\"", "");
dt.Rows[i]["RecordType"] = dt.Rows[i]["RecordType"].ToString().Replace("\"", "");
dt.Rows[i]["ProductName"] = dt.Rows[i]["ProductName"].ToString().Replace("\"", "");
dt.Rows[i]["RateId"] = dt.Rows[i]["RateId"].ToString().Replace("\"", "");
dt.Rows[i]["SubscriptionId"] = dt.Rows[i]["SubscriptionId"].ToString().Replace("\"", "");
dt.Rows[i]["PricingplanId"] = dt.Rows[i]["PricingplanId"].ToString().Replace("\"", "");
dt.Rows[i]["UsageType"] = dt.Rows[i]["UsageType"].ToString().Replace("\"", "");
dt.Rows[i]["PricingplanId"] = dt.Rows[i]["PricingplanId"].ToString().Replace("\"", "");
dt.Rows[i]["Operation"] = dt.Rows[i]["Operation"].ToString().Replace("\"", "");
dt.Rows[i]["AvailabilityZone"] = dt.Rows[i]["AvailabilityZone"].ToString().Replace("\"", "");
dt.Rows[i]["ReservedInstance"] = dt.Rows[i]["ReservedInstance"].ToString().Replace("\"", "");
dt.Rows[i]["ItemDescription"] = dt.Rows[i]["ItemDescription"].ToString().Replace("\"", "");
dt.Rows[i]["ResourceId"] = dt.Rows[i]["ResourceId"].ToString().Replace("\"", "");
dt.Rows[i]["RecordId"] = dt.Rows[i]["RecordId"].ToString().Replace("\"", "");
dt.Rows[i]["UsageQuantity"] = dt.Rows[i]["UsageQuantity"].ToString().Replace("\"", "");
dt.Rows[i]["usagestartdate"] = dt.Rows[i]["usagestartdate"].ToString() == "" ? DateTime.Now.AddYears(-2014) : Convert.ToDateTime((dt.Rows[i]["usagestartdate"].ToString().Replace("\"", "")));
dt.Rows[i]["usageenddate"] = dt.Rows[i]["usageenddate"].ToString() == "" ? DateTime.Now.AddYears(-2014) : Convert.ToDateTime((dt.Rows[i]["usageenddate"].ToString().Replace("\"", "")));
dt.Rows[i]["UsageQuantity"] = dt.Rows[i]["UsageQuantity"].ToString().Replace("\"", "");
dt.Rows[i]["BlendedRate"] = dt.Rows[i]["BlendedRate"].ToString().Replace("\"", "");
dt.Rows[i]["BlendedCost"] = dt.Rows[i]["BlendedCost"].ToString().Replace("\"", "");
dt.Rows[i]["UnBlendedRate"] = dt.Rows[i]["UnBlendedRate"].ToString().Replace("\"", "");
dt.Rows[i]["UnBlendedCost"] = dt.Rows[i]["UnBlendedCost"].ToString().Replace("\"", "");
}
}
bulkCopy.DestinationTableName = tableName;
bulkCopy.ColumnMappings.Add("InvoiceId", "invoiceid");
bulkCopy.ColumnMappings.Add("PayerAccountId", "payeraccountid");
bulkCopy.ColumnMappings.Add("LinkedAccountId", "linkedaccountid");
bulkCopy.ColumnMappings.Add("RecordType", "recordtype");
bulkCopy.ColumnMappings.Add("ProductName", "productname");
bulkCopy.ColumnMappings.Add("RateId", "rateid");
bulkCopy.ColumnMappings.Add("SubscriptionId", "subscriptionid");
bulkCopy.ColumnMappings.Add("PricingplanId", "pricingplanid");
bulkCopy.ColumnMappings.Add("UsageType", "usagetype");
bulkCopy.ColumnMappings.Add("Operation", "operation");
bulkCopy.ColumnMappings.Add("AvailabilityZone", "availabilityzone");
bulkCopy.ColumnMappings.Add("ReservedInstance", "reservedinstance");
bulkCopy.ColumnMappings.Add("ItemDescription", "itemdescription");
bulkCopy.ColumnMappings.Add("UsageStartDate", "usagestartdate");
bulkCopy.ColumnMappings.Add("UsageEndDate", "usageenddate");
bulkCopy.ColumnMappings.Add("UsageQuantity", "usagequantity");
bulkCopy.ColumnMappings.Add("BlendedRate", "blendedrate");
bulkCopy.ColumnMappings.Add("BlendedCost", "blendedcost");
bulkCopy.ColumnMappings.Add("UnBlendedRate", "unblendedrate");
bulkCopy.ColumnMappings.Add("UnBlendedCost", "unblendedcost");
bulkCopy.ColumnMappings.Add("resourceid", "resourceid");
//write the data in the "dataTable"
bulkCopy.WriteToServer(dt);
code = "Data Processed Successfully";
}
}
return code;
}
catch (Exception ex)
{
code = "Error while processing file";
System.Diagnostics.Debug.Write("EXCEPTION BulkUpload: " + ex.ToString());
}
return code;
}
I have also double checked to ensure there were no double quotes or any blank fields for now.
I get no errors, but nothing actually gets into the DB. Any ideas why? Lost a few hours trying to debug this but cannot see any issues. Read plenty of forums but lead me no where. Your help is much appreciated.
Thanks in advance.
Ok, just realised that I did not finished/committed the transaction. Funny how we need to write the code , cry for help and then we just suddenly get it.
Essentially missing...
trans.Commit();
after the bulk upload. Thanks and apologies for wasting ur time :)
After running foreach loop. I am getting NullReferenceException on second item, because query result is null. But I have more item to use on same query and get the result on richTextBox1. so have can I continue the foreach loop if there is any null result.
foreach (string Items in listBox4.Items)
{
using (OracleCommand crtCommand = new OracleCommand("select REGEXP_REPLACE(dbms_metadata.get_ddl('TABLE','" + Items + "'),('" + txtSrcUserID.Text + "...'),'', 1, 0, 'i') from dual", conn1))
{
richTextBox1.AppendText(Environment.NewLine);
richTextBox1.AppendText(crtCommand.ExecuteScalar().ToString() + ";");
richTextBox1.AppendText(Environment.NewLine);
}
}
This is dangerous programming. You really should be checking for the null. Assuming your loop will get bigger.. I would include a continue and make it a bit more obvious what it is you're doing for readability. Omit the continue if you don't need it.
var result = crtCommand.ExecuteScalar();
if (result != null) {
richTextBox1.AppendText(Environment.NewLine);
richTextBox1.AppendText(result.ToString() + ";");
richTextBox1.AppendText(Environment.NewLine);
}
else {
continue;
}
// any other code here.
Change crtCommand.ExecuteScalar().ToString() to (crtCommand.ExecuteScalar() ?? string.Empty).ToString(). This is logically equivalent to:
object dbResult = crtCommand.ExecuteScalar();
if(dbResult == null)
{
richTextBox1.AppendText(";");
}
else
{
richTextBox1.AppendText(dbResult.ToString() + ";");
}
If you want to completely ignore a null result instead of treating it as an empty string, use #SimonWhitehead's code
I'm getting content from a database and returning it for Ajax processing via Javascript. Pretty simple stuff. The issue here is that I can't seem to find a good way to loop through the data and the MSDN documentation is obscenely poor for its odbcreader methods.
using (OdbcCommand com = new OdbcCommand("SELECT * FROM pie_data WHERE Pie_ID = ?",
con)) {
if (Request.Form["reference_id"] == "") {
returnError();
} else {
com.Parameters.AddWithValue("", Request.Form["reference_id"]);
com.ExecuteNonQuery();
using (OdbcDataReader reader = com.ExecuteReader()) {
string finalstring = "";
while (reader.Read()) {
if(reader.HasRows) {
finalstring = reader.GetString(9) + ",";
for (int i = 0; i <= 8; i = i + 1) {
finalstring = finalstring + reader.GetValue(i).ToString() + ",";
}
finalstring = finalstring + "|";
reader.NextResult();
}
}
if (finalstring != "") {
finalstring = finalstring.Remove(finalstring.Length -1, 1);
Response.Write(finalstring);
}
}
noredirect = 1;
}
}
However, here is the sample output:
00001,0,Pie Johnson,piesaregreat#yum.com,,,10/7/2010 12:00:00 AM,Bakery,N/A,N/A,
As you can see, the second deliminator is not appearing at all, when it really should. Also, this query, when run in heidisql, returns a good number of rows, not just this one result. Once I have it passed to the Javascript, I can figure it out since I have much more experience with that and I've actually done this before via PHP.
I would use a DataTable and a DataAdapter:
String finalString;
var tblPieData = new DataTable();
using(var con = new OdbcConnection(connectionString))
using (OdbcDataAdapter da = new OdbcDataAdapter("SELECT * FROM pie_data WHERE Pie_ID = ?", con))
{
da.SelectCommand.Parameters.AddWithValue("Pie_ID", reference_id);
da.Fill(tblPieData);
var rowFields = tblPieData.AsEnumerable()
.Select(r => string.Join(",", r.ItemArray));
finalString = string.Join("|", rowFields);
}
You are replacing the value of finalstring in every iteration of the loop. This will cause only the values for a single row to be returned:
finalstring = reader.GetString(9) + ",";
as well as removing the last character at the end of each iteration through the columns in the rows (the pipe, not the trailing comma as I'm expecting you want):
finalstring = finalstring.Remove(finalstring.Length -1, 1);
EDIT:
It also looks like you are skipping over every other record by both looping on reader.Read() as well as calling reader.NextResult()
This line:
finalstring = finalstring.Remove(finalstring.Length -1, 1);
is going to remove the last instance of your pipe-delimiter, so if there is only one record (which there appears to be,) you shouldn't see one.
Unless I am missing something...
EDIT
Actually, if you are looking for two records, you are probably missing the second one because you start your loop with while(reader.Read()) and end it with reader.NextResult();. These will both advance the reader, causing you to miss every other record.
EDIT 2
You are also overwriting finalstring on each iteration; you probably want to append to this (making it a StringBuilder would make the most sense for efficiency's sake, if you don't know how many records to expect.)
Your looping structure with the reader appears to have some problems, not the least of which is the reset of finalAnswer within your loop and giving you only a single result combined with using both .Read() and .NextResult:
Suggested fixes...not tested, so all standard caveats apply :) :
Edited per Mark Averius' comment and OP confirmation of original intent:
using (OdbcDataReader reader = com.ExecuteReader()) {
if (reader.HasRows())
{
string finalstring = "";
while (reader.Read()) {
finalstring = finalstring + reader.GetString(9) + ",";
for (int i = 0; i <= 8; i++) {
finalstring = finalstring + reader.GetValue(i).ToString() + ",";
}
finalstring = finalstring + "|";
}
if (finalstring != "") {
finalstring = finalstring.Remove(finalstring.Length -1, 1);
Response.Write(finalstring);
}
}
}
I want to be able to display balance to label and my code is not working. This is code I got so far:
SqlDataReader readdata;
{
sqlCommandbalance.Connection.Open();
sqlCommandbalance.Parameters["#accountID"].Value = show.accoundID;
readdata = sqlCommandbalance.ExecuteReader();
string balanceDB = null;
while (readdata.Read())
{
balanceDB = readdata["balance"].ToString();
}
sqlCommandbalance.Connection.Close();
balanceShow.Text += " " + balanceDB.ToString();
}
On this line - balanceShow.Text += " " + balanceDB.ToString(); got a error saying Object reference not set to an instance of an object.
You're calling balanceDB.ToString(), when balanceDB will be null if the data reader contains no rows.
Note that balanceDB.ToString() is redundant, since balanceDB is already a string. Just take out the ToString call.
You could also initialize balanceDB as
string balanceDB = "";
Originally you set balanceDB = null;.
If no data was found, then no assignment will be made to balanceDB in the while loop, so it stays undefined.
It's because of string balanceDB = null;
Set that to string balanceDB = string.Empty; and you should be OK
Readdata.read probably returned false, making the while to never run. Thus balanceDB is still null.
Looks like your query is returning an empty set. You should check for that before you set the balanceShow.Text:
if (balanceDB != null) {
balanceShow.Text += " " + balanceDB.ToString();
} else {
// tell the user that id: show.accoundID has no balance
}
Probably your code is returing null in dataRader and consequentily you're tanking an null value on balanceDB. I recomend you do something like this:
public static string GetBalance() {
string result = string.Emtpy;
using (var connection = /* Build your SqlConnection */) {
using (var cmd = new SqlCommand("your select command here", connection) {
try
{
connection.Open();
// you don't need a reader to take just a single value
object value = cmd.ExecuteScalar();
if (value != null)
result = value.ToString();
}
catch(Exception ex)
{
/* you've got an error */
}
finally
{
connection.Close();
}
}
}
return result;
}
and in your page:
string balance = GetBalance();
if (!string.IsNullOrEmpty(balance))
balanceShow.Text += string.Contat(" ", balance);
if you wish to concat the balanceShow label, use '+=' operator, instead of this you just '='.
PS: Sorry for my english!