Background:
I am trying to add data to a SQL DB with C#. I am currently doing so in my script in another class so im using the same code (the code works). However, my current class is using a bunch of recycled code and i am having issues narrowing down why i can not write to the DB. Below is the code i am using and it is broken down to the bare bones minimum code.
What I'm asking for:
anyone to point out some dumb mistake i made or ideas where to troubleshoot. Currently i am just staring at this code and cant see whats wrong.
Thanks in advance!
public void AddAttachmentToDB(XmlNode root, XmlNamespaceManager xmlns, string MessageID, string MailBoxAliasName)
{
//open DB
#region Open DB
if (DbConnection.State != System.Data.ConnectionState.Open)
{
try
{
this.DbConnection.ConnectionString = DbConnectionString;
this.DbConnection.Open();
MailboxListener._logging.LogWrite("[{0}] opened DB Connection in AddAttachmentToDB!",
LoggingLevels.Error,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
this.DbConnectionString);
}
catch (Exception ex)
{
MailboxListener._logging.LogWrite("[{0}] Failed to open DB Connection! For Machine: {1}",
LoggingLevels.Error,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
this.DbConnectionString);
MailboxListener._logging.LogWrite("[{0}] Error Returned: {1}",
LoggingLevels.Error,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
ex.Message.ToString());
}
}
else
{
MailboxListener._logging.LogWrite("[{0}] Failed to open DB Connection in AddAttachmentToDB!",
LoggingLevels.Error,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
this.DbConnectionString);
}
#endregion
//once db is open try this
try
{
//create test variables
string strMailBoxAliasName = MailBoxAliasName;
string AttachmentFilename = string.Empty;
string strfiletype = string.Empty;
string AttachmentStream = string.Empty;
string strAttachmentID = string.Empty;
string strMessageID = string.Empty;
strMessageID = MessageID;
//fill test variables
AttachmentFilename = "yumyum";
AttachmentStream = "Cheetos";
strMessageID = "123";
strMailBoxAliasName = "user";
strfiletype = ".txt";
strAttachmentID = "12345";
//create sql insert string
String insString = #"INSERT INTO MailboxListenerAttachments Values (#attachmentfilename, #attachmentbody,
#messageID, #mailboxname, #filetype, #attachmentID, #DateAddedToDB)";
//create sql command string
SqlCommand myCommand = new SqlCommand(insString, this.DbConnection);
//add fill test variables to sql insert string
myCommand.Parameters.Add("#attachmentfilename", SqlDbType.VarChar, 100);
myCommand.Parameters["#attachmentfilename"].Value = AttachmentFilename;
myCommand.Parameters.Add("#attachmentbody", SqlDbType.VarChar, 8000);
myCommand.Parameters["#attachmentbody"].Value = AttachmentStream.Trim();
myCommand.Parameters.Add("#messageID", SqlDbType.VarChar, 500);
myCommand.Parameters["#messageID"].Value = strMessageID;
myCommand.Parameters.Add("#mailboxname", SqlDbType.VarChar, 100);
myCommand.Parameters["#mailboxname"].Value = strMailBoxAliasName;
myCommand.Parameters.Add("#filetype", SqlDbType.VarChar, 50);
myCommand.Parameters["#filetype"].Value = strfiletype;
myCommand.Parameters.Add("#attachmentID", SqlDbType.VarChar, 50);
myCommand.Parameters["#attachmentID"].Value = strAttachmentID;
myCommand.Parameters.Add("#DateAddedToDB", SqlDbType.DateTime);
myCommand.Parameters["#DateAddedToDB"].Value = DateTime.UtcNow.ToString();
//run sql command
myCommand.ExecuteNonQuery();
//log sql command events
MailboxListener._logging.LogWrite(
"[{0}] Added attachment {1} to database for messageID: {2}",
LoggingLevels.Informational,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
AttachmentFilename,
strMessageID
);
//if DB is open, close it
if (DbConnection.State == System.Data.ConnectionState.Open)
{
this.DbConnection.Close();
}
}
//catch errors
catch (Exception ex)
{
MailboxListener._logging.LogWrite("[{0}] Error Returned: {1}",
LoggingLevels.Error,
System.Reflection.MethodBase.GetCurrentMethod().ToString(),
ex.Message.ToString());
}
}
No idea why this doesn't work but this code screams for refactoring:
public void AddAttachmentToDB(
XmlNode root,
XmlNamespaceManager xmlns,
string MessageID,
string MailBoxAliasName
)
{
var strMailBoxAliasName = MailBoxAliasName;
var AttachmentFilename = "yumyum";
var AttachmentStream = "Cheetos";
var strMessageID = "123";
var strMailBoxAliasName = "user";
var strfiletype = ".txt";
var strAttachmentID = "12345";
// Use DateTime when working with dates
var dates123 = new DateTime(2011, 2, 3);
try
{
using (var conn = new SqlConnection(DbConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = #"INSERT INTO MailboxListenerAttachments Values (#attachmentfilename, #attachmentbody, #messageID, #mailboxname, #filetype, #attachmentID, #DateAddedToDB";
cmd.Parameters.AddWithValue("#attachmentfilename", AttachmentFilename);
cmd.Parameters.AddWithValue("#attachmentbody", AttachmentStream.Trim());
cmd.Parameters.AddWithValue("#messageID", strMessageID);
cmd.Parameters.AddWithValue("#mailboxname", strMailBoxAliasName);
cmd.Parameters.AddWithValue("#filetype", strfiletype);
cmd.Parameters.AddWithValue("#attachmentID", strAttachmentID);
cmd.Parameters.AddWithValue("#DateAddedToDB", dates123);
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
// TODO: Log the exception and propagate it
throw ex;
}
}
Shouldn't Dates123 be of a DateTime type instead of a string?
I think you need to specify input/output directions for all of the paramters.
for example : myCommand.Parameters["#attachmentfilename"].Direction = ParameterDirection.Input
If you really have no idea you can try
Fix your insert statement so it
explicitly names columns maybe your
ordering is incorrect and insert
statement doesnt work
your setting parameters length to
maximum column length values, maybe you
need to set them to actual parameter
values length
I really think that Dates123 is
indeed the most important problem here, it
should be DateTime not string.
So you changed it but you still call DateTime.UtcNow.ToString() , leave it as DateTime type not string.
Related
This seems to be a problem either with my computer or the azure sql servers. The problem I have was not a problem before but the code all of a sudden acting strange. Here is my code that is used to work. Connection opens successfully, my executenonquery works fine but reader acts strange.
public static List<ClientDto> GetClientInformation()
{
List<ClientDto> results = new List<ClientDto>();
try
{
using (var sqlConnection =
new SqlConnection(ConfigurationManager.ConnectionStrings["ClientData"].ConnectionString))
{
using (var command = new SqlCommand(null, sqlConnection))
{
sqlConnection.Open();
command.CommandType = CommandType.StoredProcedure;
//running the GetClientInformation stored procedure in DB
command.CommandText = Constants.GetClientInformation;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
results.Add(new ClientDto()
{
Id = Convert.ToInt32(reader["Id"].ToString()),
DealerName = reader["DealerName"].ToString(),
GroupID = reader["GroupID"].ToString(),
DealerId = reader["DealerId"].ToString(),
DealerFolderName = reader["DealerFolder"].ToString(),
DMSType = reader["DMSType"].ToString(),
MAIsActive = Convert.ToBoolean(Convert.ToInt32(reader["MAIsActive"])),
SalesIsActive = Convert.ToBoolean(Convert.ToInt32(reader["SalesIsActive"])),
SalesSource = reader["SalesSource"].ToString(),
InventoryIsActive = Convert.ToBoolean(Convert.ToInt32(reader["InventoryIsActive"])),
InventorySource = reader["InventorySource"].ToString(),
AppointmentsIsActive =
Convert.ToBoolean(Convert.ToInt32(reader["AppointmentsIsActive"])),
AppointmentsSource = reader["AppointmentsSource"].ToString(),
LeadsIsActive = Convert.ToBoolean(Convert.ToInt32(reader["LeadsIsActive"])),
LeadsSource = reader["LeadsSource"].ToString(),
ServiceIsActive = Convert.ToBoolean(Convert.ToInt32(reader["ServiceIsActive"])),
ServiceSource = reader["ServiceSource"].ToString(),
SalesIsDelete = Convert.ToBoolean(Convert.ToInt32(reader["SalesIsDelete"])),
SalesDeleteRange = reader["SalesDeleteRange"].ToString(),
InventoryIsDelete = Convert.ToBoolean(Convert.ToInt32(reader["InventoryIsDelete"])),
InventoryDeleteRange = reader["InventoryDeleteRange"].ToString(),
AppointmentsIsDelete =
Convert.ToBoolean(Convert.ToInt32(reader["AppointmentsIsDelete"])),
AppointmentsDeleteRange = reader["AppointmentsDeleteRange"].ToString(),
LeadsIsDelete = Convert.ToBoolean(Convert.ToInt32(reader["LeadsIsDelete"])),
LeadsDeleteRange = reader["LeadsDeleteRange"].ToString(),
ServiceIsDelete = Convert.ToBoolean(Convert.ToInt32(reader["ServiceIsDelete"])),
ServiceDeleteRange = reader["ServiceDeleteRange"].ToString(),
IsActive = Convert.ToBoolean(Convert.ToInt32(reader["IsActive"])),
UserDefinedName = reader["UserDefinedName"].ToString()
});
}
}
}
return results;
}
catch (Exception ex)
{
//If an exception happens it will insert the error to errorlog table and to the log file
Logger.WriteError(new ErrorDto()
{
Source = "GetClientInformation",
Message = ex.Message,
StackTrace = ex.StackTrace
});
Console.WriteLine(string.Format("Error - {0} - {1} ", "GetClientInformation", ex.Message));
return results;
}
}
There is data in the sql, the executable of my application works fine on our virtual machine (Windows Server).
Only strange thing I see in the code is that SQLConnection have this innerexception (it is not stopping the code to run though)
ServerVersionNormalized = 'sqlConnection.InnerConnection.ServerVersionNormalized' threw an exception of type 'System.NotSupportedException'
I am not sure if this was an issue before or not.
This picture shows that Enamration yielded no result
This picture shows that reader has rows
I am reinstalling my visual studio now to see if it will fix the issue.
This issue is happening in both Visual Studio 2015 and 2017 for me.
This is my connection string format:
Server=.database.windows.net,1433;Database=; User ID=;Password=;Trusted_Connection=False; Encrypt=True;
It looks like it is working fine now. To me it sounds like since I had breakpoint in the code, it might have caused the issue because of the longer time between connecting and running the query.
I have code that I copied from the tutorial that I watch and our code is so similar in the tutorial.
When the presenter runs the code, it runs ok, but when I try to run my code which is the same as in the tutorial, I get an error "the parameter is not valid".
Please help
private void Viewbutton_Click(object sender, EventArgs e)
{
conection.Open();
string sqlQuery = "select studnum, course, f_name, l_name, color_image from table3 where studnum='" + textBox1.Text + "'";
cmd = new SqlCommand(sqlQuery, conection);
SqlDataReader dataread = cmd.ExecuteReader();
dataread.Read();
if (dataread.HasRows)
{
lblstudnum.Text = dataread[0].ToString();
lblcourse.Text = dataread[1].ToString();
lblfname.Text = dataread[2].ToString();
lbllname.Text = dataread[3].ToString();
byte[] images = (byte[])dataread[4];
if(images==null)
{
pictureBox1.Image = null;
}
else
{
MemoryStream mstreem = new MemoryStream(images);
pictureBox1.Image = Image.FromStream(mstreem);
}
}
else
{
MessageBox.Show("this data not available");
}
}
The error line is the
pictureBox1.Image = Image.FromStream(mstreem);
Better to use parametric query and column name instead of using [0],[1] etc.. The Memory Stream is used by Data reader.So you shall use as below, provided a valid Image is saved in database
var con = new SqlConnection("the connection string to database");
con.Open();
SqlCommand cmd = new SqlCommand(#"sql query",con);
byte[] images = null;
using (SqlDataReader dataread = cmd.ExecuteReader())
{
if (dataread.Read())
{
//lblstudnum.Text = dataread[0].ToString();
//lblcourse.Text = dataread[1].ToString();
//lblfname.Text = dataread[2].ToString();
//lbllname.Text = dataread[3].ToString();
images = (byte[])dataread["color_image"];// column name is recommended
}
}
con.Close();
if (images == null)
{
pictureBox1.Image = null;
}
else
{
MemoryStream mstreem = new MemoryStream(images);
pictureBox1.Image = Image.FromStream(mstreem);
}
Probably not a valid image. Add some debugging code to your program (or set up a watch) that will output the length of the memory stream and its first few bytes. Make sure the length is what you were expecting. Make sure the file prefix is there, if any, e.g. bitmap files have a two-letter alphanumeric prefix. Make sure it didn't get truncated. Make sure it is an allowed file format. The problem may be that your instructor's database has data in it while yours doesn't.
I am using MySql 5.6x with Visual Studio 2015, windows 10, 64-bit. C# as programming language. In my CRUD.cs (Class file) i have created the following method:
public bool dbQuery(string sql,string[] paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null){
foreach(string i in paramList){
string[] valus = i.Split(',');
string p = valus[0];
string v = valus[1];
cmd.Parameters[p].Value = v;
}
}
if (cmd.ExecuteNonQuery() > 0)
{
flag = true;
}
}
catch (Exception exc)
{
error(exc);
}
}
I am passing the query and Parameters List like this:
protected void loginBtn_Click(object sender, EventArgs e)
{
string sql = "SELECT * FROM dept_login WHERE (user_email = ?user_email OR user_cell = ?user_cell) AND userkey = ?userkey";
string[] param = new string[] {
"?user_email,"+ userid.Text.ToString(),
"?user_cell,"+ userid.Text.ToString(),
"?userkey,"+ userkey.Text.ToString()
};
if (db.dbQuery(sql, param))
{
msg.Text = "Ok";
}
else
{
msg.Text = "<strong class='text-danger'>Authentication Failed</strong>";
}
}
Now the problem is that after the loop iteration complete, it directly jumps to the catch() Block and generate an Exception that:
Parameter '?user_email' not found in the collection.
Am i doing this correct to send params like that? is there any other way to do the same?
Thanks
EDIT: I think the best way might be the two-dimensional array to collect the parameters and their values and loop then within the method to fetch the parameters in cmd.AddWidthValues()? I may be wrong...
In your dbQuery you don't create the parameters collection with the expected names, so you get the error when you try to set a value for a parameter that doesn't exist
public bool dbQuery(string sql,string[] paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null){
foreach(string i in paramList){
string[] valus = i.Split(',');
string p = valus[0];
string v = valus[1];
cmd.Parameters.AddWithValue(p, v);
}
}
if (cmd.ExecuteNonQuery() > 0)
flag = true;
}
catch (Exception exc)
{
error(exc);
}
}
Of course this will add every parameter with a datatype equals to a string and thus is very prone to errors if your datatable columns are not of string type
A better approach would be this one
List<MySqlParameter> parameters = new List<MySqlParameter>()
{
{new MySqlParameter()
{
ParameterName = "?user_mail",
MySqlDbType= MySqlDbType.VarChar,
Value = userid.Text
},
{new MySqlParameter()
{
ParameterName = "?user_cell",
MySqlDbType= MySqlDbType.VarChar,
Value = userid.Text
},
{new MySqlParameter()
{
ParameterName = "?userkey",
MySqlDbType = MySqlDbType.VarChar,
Value = userkey.Text
},
}
if (db.dbQuery(sql, parameters))
....
and in dbQuery receive the list adding it to the parameters collection
public bool dbQuery(string sql, List<MySqlParameter> paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null)
cmd.Parameters.AddRange(paramList.ToArray());
if (cmd.ExecuteNonQuery() > 0)
{
flag = true;
}
}
catch (Exception exc)
{
error(exc);
}
}
By the way, unrelated to your actual problem, but your code doesn't seem to close and dispose the connection. This will lead to very nasty problems to diagnose and fix. Try to use the using statement and avoid a global connection variable
EDIT
As you have noticed the ExecuteNonQuery doesn't work with a SELECT statement, you need to use ExecuteReader and check if you get some return value
using(MySqlDataReader reader = cmd.ExecuteReader())
{
flag = reader.HasRows;
}
This, of course, means that you will get troubles when you want to insert, update or delete record where instead you need the ExecuteNonQuery. Creating a general purpose function to handle different kind of query is very difficult and doesn't worth the work and debug required. Better use some kind of well know ORM software like EntityFramework or Dapper.
Your SQL Commands' Parameters collection does not contain those parameters, so you cannot index them in this manner:
cmd.Parameters[p].Value = v;
You need to add them to the Commands' Parameters collection in this manner: cmd.Parameters.AddWithValue(p, v);.
I have the following code. The program just exits, no value returned from call. Any ideas?
AS400System system = new AS400System();
system.Define(ConfigurationManager.AppSettings["AS400Server"]);
system.UserID = ConfigurationManager.AppSettings["AS400User"];
system.Password = ConfigurationManager.AppSettings["AS400Password"];
system.IPAddress = "10.98.1.21";
system.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd);
if(system.IsConnected(cwbcoServiceEnum.cwbcoServiceRemoteCmd) == 1) {
Program program = new Program();
program.LibraryName = "P2PTST";
program.ProgramName = "AUI0XFR";
program.system = system;
program.system.Signon();
string paramStatus = "A";
Int64 paramStockItem = Int64.Parse(t.EtagNumber);
Guid paramGuid = Guid.NewGuid();
string paramReturn;
StringConverter stringConverter = new StringConverter();
ProgramParameters parameters = new ProgramParameters();
parameters.Append("ApiIGuid", cwbrcParameterTypeEnum.cwbrcInout, 38);
parameters.Append("StockItemNumber", cwbrcParameterTypeEnum.cwbrcInout, 20);
parameters.Append("ItemStatus", cwbrcParameterTypeEnum.cwbrcInout, 1);
parameters.Append("ReturnCode", cwbrcParameterTypeEnum.cwbrcInout, 7);
parameters["ApiIGuid"].Value = stringConverter.ToBytes(paramGuid.ToString().PadRight(38, ' '));
parameters["StockItemNumber"].Value = stringConverter.ToBytes(paramStockItem.ToString().PadRight(20, ' '));
parameters["ItemStatus"].Value = stringConverter.ToBytes(paramStatus.ToString());
try{
program.Call(parameters);
paramReturn = stringConverter.FromBytes(parameters["ReturnCode"].Value);
system.Disconnect(cwbcoServiceEnum.cwbcoServiceAll);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
We just went through this and had the same issues, so decided to create and use a stored procedure to accomplish this in .NET. Because we were concerned about having the 400 side distribute the code to create a stored procedure, it ended up being very quick to go ahead and create the procedure on the PC side, followed by our remote command, so no additional changes were necessary on the 400 side.
My environment is Win7 x64 running VS2012 C#, CAX V7.1, and importing both IBM.Data.DB2.iSeries, and System.Data;
I need System.Data for the Parameters. That ended up being critical to get data back!
I send the 400 two params, filesetID and a name. I get back a number and a uuid.
(but they are all characters!)
It looks something like this:
public void RemoteCmd(ref PicMeta pm)
{
iDB2Connection cn;
try
{
using (cn = new iDB2Connection("DataSource=<servername/IP>; UserID="<user>"; Password="<pass>";"))
{
cn.Open();
using (iDB2Command cm = cn.CreateCommand())
{
//Place a try/catch here, so it will create the procedure the first time, or any time it has been removed from the 400. If already set, it will fail, and you'll go directly to the remote command.
try
{
//Here we create a procedure and execute or continue.
cm.CommandText = "CREATE PROCEDURE LIBRARY.SP_PICGETID(INOUT FSET CHAR (1 ), INOUT UNIT CHAR (6 ), INOUT NEXTID CHAR (3 ), INOUT UUID CHAR (36 )) LANGUAGE RPGLE NOT DETERMINISTIC NO SQL CALLED ON NULL INPUT EXTERNAL NAME LIBRARY.PICGETID PARAMETER STYLE GENERAL";
cm.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
}
//Continue - create and call the command
//ParameterDirection needs "using System.Data;"
cm.CommandTimeout = 0;
cm.CommandType = System.Data.CommandType.StoredProcedure;
cm.CommandText = "LIBRARY.SP_PICGETID";
iDB2Parameter p = new iDB2Parameter();
p.ParameterName = "FSET";
p.Direction = ParameterDirection.Input;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 1;
p.iDB2Value = pm.fileset;
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "UNIT";
p.Direction = ParameterDirection.Input;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 6;
p.iDB2Value = pm.unit;
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "NEXTID";
p.Direction = ParameterDirection.InputOutput;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 3;
p.iDB2Value = "";
cm.Parameters.Add(p);
p = new iDB2Parameter();
p.ParameterName = "GUUID";
p.Direction = ParameterDirection.InputOutput;
p.iDB2DbType = iDB2DbType.iDB2Char;
p.Size = 36;
p.iDB2Value = "";
cm.Parameters.Add(p);
cm.ExecuteNonQuery();
iDB2ParameterCollection pc = cm.Parameters;
//We get our Out parameters here
pm.nextid = pc["NEXTID"].Value.ToString();
pm.uuid = pc["GUUID"].Value.ToString();
}
cn.Close();
}
}
catch (Exception e)
{
Console.Out.WriteLine(e.Message);
}
return;
}
Hope this helps!
My database is in SQL Server and I use Linq-to-SQL. I used from SP(Save cards) .
I put breakpoint in my code, when arrive at rdr = cmm.ExecuteReader(); get me exception!!!
private void btnSave_Click(object sender, EventArgs e)
{
PersianCalendar jc = new PersianCalendar();
string SaveDate = jc.GetYear(DateTime.Now).ToString();
int from=Convert.ToInt32(txt_barcode_f.Text);
int to=Convert.ToInt32(txt_barcode_t .Text);
int quantity=Convert.ToInt32(to-from);
int card_Type_ID=Convert.ToInt32(cmb_BracodeType .SelectedValue);
int[] arrCardNum = new int[quantity];
arrCardNum[0]=from;
for (int i = from; i < to;i++ )
{
for(int j=0; j<quantity ;j++)
{
arrCardNum[j]=from+j;
int r = arrCardNum[j];
sp.SaveCards(r, 2, card_Type_ID, SaveDate, 2);
}
}
}
public void SaveCards(int Barcode_Num, int Card_Status_ID, int Card_Type_ID, string Save_Date, int Save_User_ID)
{
IDbCommand cmm;
cmm = Linq.Connection.CreateCommand();
try
{
cmm.Parameters.Add(new SqlParameter("#Barcode_Num", Barcode_Num));
cmm.Parameters.Add(new SqlParameter("#Card_Status_ID", 2));
cmm.Parameters.Add(new SqlParameter("#Card_Type_ID", Card_Type_ID));
cmm.Parameters.Add(new SqlParameter("#SaveDate", Save_Date));
cmm.Parameters.Add(new SqlParameter("#Save_User_ID", Save_User_ID));
cmm.CommandText = "SaveCards";
cmm.Connection.Open();
cmm.Connection = Linq.Connection;
cmm.CommandType = CommandType.StoredProcedure;
IDataReader rdr = null;
**rdr = cmm.ExecuteReader();**
while (rdr.Read())
{
Console.Write(" All Insert ! " + "\n");
}
}
catch (SqlException ex)
{
SqlExceptionHandler(ex, Save_User_ID);
}
catch (Exception ex)
{
PopularEexceptionHandler(ex, Save_User_ID);
}
finally
{ cmm.Connection.Close(); }
}
when excute sp, show no result and display this:
when execute sp , display this:The INSERT statement conflicted with the CHECK constraint "CK_BarCode_Num". The conflict occurred in database "Parking", table "dbo.TBL_Cards", column 'BarCode_Num'. The statement has been terminated. No rows affected. (0 row(s) returned) #RETURN_VALUE = -6
You're a bit chaotic on how you set up your connection and command..... e.g. you open the connection before you even assign it! How is that going to work??
My recommendation would be this order (based on the principle first do all the setup before opening the connection, and furthermore open the connection as late as possible, close it as quickly as possible) :
IDbCommand cmm = Linq.Connection.CreateCommand();
try
{
// define name and type of command
cmm.CommandText = "SaveCards";
cmm.CommandType = CommandType.StoredProcedure;
// assign connection
cmm.Connection = Linq.Connection;
// define parameters
cmm.Parameters.Add(new SqlParameter("#Barcode_Num", Barcode_Num));
cmm.Parameters.Add(new SqlParameter("#Card_Status_ID", 2));
cmm.Parameters.Add(new SqlParameter("#Card_Type_ID", Card_Type_ID));
cmm.Parameters.Add(new SqlParameter("#SaveDate", Save_Date));
cmm.Parameters.Add(new SqlParameter("#Save_User_ID", Save_User_ID));
// only now - after all the setup - open the connection, read the data
cmm.Connection.Open();
IDataReader rdr = rdr = cmm.ExecuteReader();
while (rdr.Read())
{
....
}
}
To catch the errors that the execution throws, replace your catch block for the SqlException with this:
catch (SqlException ex)
{
StringBuilder sbErrors = new StringBuilder();
foreach (SqlError error in ex.Errors)
{
sbErrors.AppendLine(error.Message);
}
string allErrors = sbErrors.ToString();
}
and debug into that catch block - what is the allErrors string in the end??
Update: after a chat session, we know finally know what the message in the SQL exception is:
The INSERT statement conflicted with the CHECK constraint "CK_BarCode_Num". The conflict occurred in database "Parking", table "dbo.TBL_Cards", column 'BarCode_Num'.
Now we're trying to find out what that constraint is / does and why it gets violated....
I think it could be that you have open the connection and assigning another connection before executing the reader.
cmm.CommandText = "SaveCards";
//cmm.Connection.Open(); You should open the connection after assigning it
cmm.Connection = Linq.Connection;
cmm.CommandType = CommandType.StoredProcedure;
cmm.Connection.Open(); //Open it here
SqlDataReader rdr = cmm.ExecuteReader();