No error was complained!
The following program is to write a whole year's month,day,weekday in a MSSQL table. But somehow, for many times I have tried, but each time I got only part of what I intend to get: the whole year with 12 monthes, instead, I only got 3 or 4 months' content in the table. Can anybody tell me why
calendar.dll
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using database;
namespace calendar
{
public class calendar
{
private int _nian; //year
private int _yue; //month
private int _ri; //day
private int _xingqi; //weekday
private string _errorInfo;
public int nian
{
get {return _nian;}
set {_nian=value;}
}
public int yue
{
get {return _yue;}
set {_yue=value;}
}
public int ri
{
get {return _ri;}
set {_ri=value;}
}
public int xingqi
{
get {return _xingqi;}
set {_xingqi=value;}
}
public string errorInfo
{
get {return _errorInfo;}
}
private void InsertAMonth(int x) //x indicates 30 days or 31 days in that month
{
try
{
DBClass db = new DBClass();
db.ConnStr = ConfigurationSettings.AppSettings["cstr_calendar"];
for (int i = 1; i<=x; i++)
{
_ri = i;
db.Sql = "insert into solar (nian,yue,ri,xingqi) values ('"+_nian+"','"+_yue+"','"+_ri+"','"+_xingqi+"')"; //insert year,month,day,weekday respectively
db.exeSql();
if (_xingqi < 7)
{_xingqi += 1;}
else
{_xingqi = 1;} //weekdays' value is from 1 to 7
}
db.clear();
}
catch (System.Exception E)
{
_errorInfo = E.ToString();
}
}
public bool InsertAYear(int x) //x indicates a year,such as 2006
{
try
{
_nian = x;
for (int j = 1; j<=12; j++)
{
switch(j)
{
case 1: _yue = 1; InsertAMonth(31); break;
case 2: _yue = 2; InsertAMonth(28); break;
case 3: _yue = 3; InsertAMonth(31); break;
case 4: _yue = 4; InsertAMonth(30); break;
case 5: _yue = 5; InsertAMonth(31); break;
case 6: _yue = 6; InsertAMonth(30); break;
case 7: _yue = 7; InsertAMonth(31); break;
case 8: _yue = 8; InsertAMonth(31); break;
case 9: _yue = 9; InsertAMonth(30); break;
case 10: _yue =10; InsertAMonth(31); break;
case 11: _yue = 11; InsertAMonth(30); break;
case 12: _yue = 12; InsertAMonth(31); break;
}
}
return true;
}
catch(System.Exception E)
{
_errorInfo = E.ToString();
return false;
}
}
}
}
calendar.aspx:
<%@ Register TagPrefix="database" Namespace="database" Assembly="database"%>
<%@ Register TagPrefix="calendar" Namespace="calendar" Assembly="calendar"%>
<%@ Page language="C#" Debug="true"%>
<script language="C#" runat="server">
void Page_Load(Object Sender , EventArgs E)
{
calendar cl = new calendar();
cl.xingqi = 6; // the very first day of year 1921 is Saturday, here 6 means Saturday
try
{
if(cl.InsertAYear(1921))
{
Response.Write("success!");
}
else {Response.Write("Failure!");}
}
catch
{
Response.Write(cl.errorInfo);
}
}
</script>

NO error, but I got only part of what I want to get.
J. Clark
you are right, thks.
now I got an error:
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached. at System.Data.SqlClient.SqlConnectionPoolManager.GetPooledConnection(SqlConnectionString options, Boolean& isInTransaction) at System.Data.SqlClient.SqlConnection.Open() at database.DBClass.connDb() at database.DBClass.exeSql() at calendar.calendar.InsertAMonth(Int32 x)
How to handle this
Johnny606
You could actually be getting an exception within your InsertAMonth method, but not be aware of it because you have coded it to catch and store the detail in _errorInfo, but because you are not re-throwing the exception it will never get up to InsertAYear and hence cause the program to terminate with false. Try writing out the value of _errorInfo for each attempted call of InsertAMonth or change the error handler in InsertAMonth to be:
catch (System.Exception E)
{
throw new Exception("Error in InsertAMonth", E);
//_errorInfo = E.ToString();
}
Indigox3
InsertAMonth(31)
InsertAMonth(28)
InsertAMonth(31)
InsertAMonth(30)
InsertAMonth(31)
InsertAMonth(30)
InsertAMonth(31)
InsertAMonth(31)
InsertAMonth(30)
InsertAMonth(31)
InsertAMonth(30)
InsertAMonth(31)
But I don't know why you're only getting part of the output you expect...
MikeMalone
You are right, the for and select case loop is not necessary.
But my problem is that I can get only 3 or 4 months' content in the MSSQL table. What is the problem
Neal Hudson
This problem is solved now.
exeSql method of DBClass resulted in the error, because it opened a new connection to DB each time the SQL command was executed but the connection was not properly closed, thus ate up all the available DB connection.
Now I have changed the code, it works smoothly now.
Thank you all who has helped me in this problem in various ways. All of your generous help has done me much good.
Thank you all again!
brad0999
That won't work because you are calling return in your catch block. What you could do is have a bool indicated success and set it to false in you catch block, or to true at the end of the try, then return it outside of the try, catch, finally. i.e
bool isSuccessful;
try
{
.... do stuff ...
isSuccessful = true;
}
catch (Exception e)
{
.... log error info ...
isSuccessful = false;
}
finally
{
... clean up stuff ...
}
return isSuccessful;
Better still, get your DBClass to implement IDisposable, making sure the necessary cleanup code is in its Dispose method, and then wrap you InsertAMonth logic in a using() clause..... down side to that being that you won't explicitly return a flag indicating success, you'll have to infer that based on the fact you had an exception raised from the method - but that shouldn't ruin your day :-)
using (DBClass db = new DBClass())
{
.... logic to insert a month ...
db.clear();
}
MMMalik
Thanks a lot.
I already changed InsertAMonth code as this, but the error still exists:
private bool InsertAMonth(int x)
{
DBClass db = new DBClass();
try
{
db.ConnStr = ConfigurationSettings.AppSettings["cstr_calendar"];
for (int i = 1; i<=x; i++)
{
_ri = i;
db.Sql = "insert into solar (nian,yue,ri,xingqi) values ('"+_nian+"','"+_yue+"','"+_ri+"','"+_xingqi+"')";
db.exeSql();
if (_xingqi < 7)
{_xingqi += 1;}
else
{_xingqi = 1;}
}
return true;
}
catch (System.Exception E)
{
_errorInfo = E.ToString();
return false;
}
finally
{
db.clear(); // Here I put db.clear in finally bracket, so it will surely be executed, right
db = null;
}
}
database.dll is as follows:
using System;
using System.Data;
using System.Data.SqlClient;
namespace database
.Message+ "\n" + "Error Source:" +e.Errors
.Source+ "\n" + "Program:" +e.Errors
.Procedure;
{
public class DBClass
{
private SqlConnection conn;
private SqlCommand comm;
public SqlDataReader dr;
public DataSet ds;
public SqlDataAdapter dad;
public DataView dv;
private string sql;
private string connStr;
private string errInfo;
public void database()
{
errInfo = "";
}
public string ErrInfo
{
get {return errInfo;}
}
public string Sql
{
get {return sql;}
set {sql=value;}
}
public string ConnStr
{
get {return connStr;}
set {connStr=value;}
}
private void connDb()
{
conn = new SqlConnection(connStr);
try
{
conn.Open();
}
catch(SqlException e)
{
for(int i=0;i<e.Errors.Count;i++)
{
errInfo+="Error Sequential Number:" +i+ "\n" + "Error Info:" +e.Errors
}
conn.Close();
}
}
public void dataView()
{
connDb();
dad = new SqlDataAdapter(sql,conn);
ds = new DataSet();
dad.Fill(ds,"article");
dv = new DataView(ds.Tables["article"]);
}
public void readerData()
{
connDb();
comm = new SqlCommand(sql,conn);
dr = comm.ExecuteReader();
}
public void exeSql()
{
connDb();
comm = new SqlCommand(sql,conn);
comm.ExecuteNonQuery();
}
public void clear() // clear method should be able to ensure a connection be closed once InsertAMonth is completed
{
conn.Close();
comm = null;
dr = null;
ds = null;
dad = null;
dv = null;
}
}
}
looplocal