Try statement not executing - goes straight to catch - c#

I am setting up a winform that takes the first name, last name, and student ID of a student into an sql database named college, and performs a stored procedure which searches for that student, then displays the results in a DataGridView when the search button is pressed. Whenever I press the search button I get the following error
"A first chance exception of type 'System.TypeInitializationException' occurred in Search2.exe".
My program is skipping over the Try block shown, and going to the Catch statement. Can anyone tell me why this is?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Search2
{
public partial class frmSearch : Form
{
public frmSearch()
{
InitializeComponent();
}
private void btnSearch_Click(object sender, EventArgs e)
{
string studid, fname, lname;
try
{
// get the values
fname = txtFname.Text.Trim();
lname = TxtLname.Text.Trim();
studid = txtStudentID.Text.Trim();
//instantiate datatier
Class1 astudent = new Class1();
DataSet ds = new DataSet();
ds = astudent.GetStudents(studid, fname, lname);
// populate the datagrid with dataset
dgvStudents.DataSource = ds.Tables[0];
}
catch (Exception ex)
{
}
}
private void frmSearch_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'collegeDataSet.STUDENT' table. You can move, or remove it, as needed.
//this.sTUDENTTableAdapter.Fill(this.collegeDataSet.STUDENT);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Data.SqlClient;
using System.Globalization;
namespace Search2
{
class Class1: frmSearch
{
static String connString = ConfigurationManager.ConnectionStrings["Data Source=EVEDELL17;Initial Catalog=College;Integrated Security=True"].ConnectionString;
static SqlConnection myConn = new SqlConnection(connString);
static System.Data.SqlClient.SqlCommand cmdString = new System.Data.SqlClient.SqlCommand();
public DataSet GetStudents(string studid, string fname, string lname)
{
try
{
// Open Connection
myConn.Open();
//clear command argument
cmdString.Parameters.Clear();
//command
cmdString.Connection = myConn;
cmdString.CommandType = CommandType.StoredProcedure;
cmdString.CommandTimeout = 1500;
cmdString.CommandText = "SearchStudent";
// define input parameter
cmdString.Parameters.Add("#fname", SqlDbType.VarChar, 1).Value = fname;
cmdString.Parameters.Add("#lname", SqlDbType.VarChar, 25).Value = lname;
// adapter and daraset
SqlDataAdapter aAdapter = new SqlDataAdapter();
aAdapter.SelectCommand = cmdString;
DataSet aDataSet = new DataSet();
// fill adapter
aAdapter.Fill(aDataSet);
//return Dataset
return aDataSet;
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message);
}
finally
{
myConn.Close();
}
}
}
}

Judging by the exception type--TypeInitializationException--I suspect the problem is with the static field initializers:
static String connString = ConfigurationManager.ConnectionStrings["Data Source=EVEDELL17;Initial Catalog=College;Integrated Security=True"].ConnectionString;
static SqlConnection myConn = new SqlConnection(connString);
static System.Data.SqlClient.SqlCommand cmdString = new System.Data.SqlClient.SqlCommand();
Those initializers will run the first time their containing class (Class1) is "touched" by the runtime. Because they aren't in a method, it's hard for the compiler to give a helpful stack trace when they fail. Try replacing the inline initializers with a static constructor:
static String connString;
static SqlConnection myConn;
static System.Data.SqlClient.SqlCommand cmdString;
static Class1() {
connString = ConfigurationManager.ConnectionStrings["Data Source=EVEDELL17;Initial Catalog=College;Integrated Security=True"].ConnectionString;
myConn = new SqlConnection(connString);
cmdString = new System.Data.SqlClient.SqlCommand();
}
I think you'll get a better error message that way. You can also set a breakpoint in the constructor to see exactly what happens during initialization.
Read more here: https://learn.microsoft.com/en-us/dotnet/api/system.typeinitializationexception?view=netframework-4.8#Static

Xander got the answer I think: Something goes "bump" when initializing those static fields. And static/type constructors are notoriously poor at communicating exceptions:
https://learn.microsoft.com/en-us/dotnet/api/system.typeinitializationexception
The underlying problem however, is one of pattern. And there are several issues. However you can often fudge these parts for simple learning examples.
Disposeable
SqlConnectons is Disposeable, as it contains some unmanaged resources. Always dispose of disposeables. My personal rule is:
never split the Creation and Disposing of a Disposeable resource. Create, Use, Dispose. All in the same piece of code - ideally using a using statement/block.
The rare exception is if you wrap around something disposeable that you can not Dispose (or even just might ocassionally). In that case implent the Dispose pattern yourself, with the sole purpose of relaying the Dispose() call. (Approxmialtey 95% of all classes are only Disposeable because of this).
Avoid Globals/Static
Static variables are global variables. And quicklly after inventing those, we realized that using either was a terrible idea 90% of the time. Particular for exchanging/sharing data.
While I go even a bit further, never have a field that is static and can be written. constant and readonly (runtime constants) should be the only statics you ever use. If you can not make it that, do not make it static. Stuff like connection strings are way up on that rule. If you can not tag it like that, do not make it a static to begin with.
At tops I make a class, struct or tupple. And assign a instance of it to a static readonly/constant variable. Stuff like connection strings are either a instance variable, or handed in on each call of a function like GetStudents. Indeed, Class1 looks a lot like a DB access abstraction. And those in particular fall under the "do not make static" rule.

Related

Basic inserting data into SQL Server database

I'm a newbie in Visual Studio and I want to make a database system that allows the user to insert, update, delete and search data using a Windows Forms application.
I already watched 3 tutorial how but I'm getting the same error. when I delete my ExecuteNonQuery() call, it doesn't have any error but the data I entered into my textboxes is not inserted into my database. When I put it back I'm getting this kind of error
ERROR:
CODE:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void InsertButton_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = new SqlCommand("Insert Into EAGLEPLANNERS(policy number,plan type,renewal date,name,age,address,birthday,email,home/office number,mode of payment,amount) values (#policy number,#plan type,#renewal date,#name,#age,#address,#birthday,#email,#home/office number,#mode of payment,#amount)", connection);
cmd.Parameters.AddWithValue("#policy number", int.Parse(policyNumbertxtbox.Text));
cmd.Parameters.AddWithValue("#plan type", planTypetxtbox.Text);
cmd.Parameters.AddWithValue("#renewal date", int.Parse(renewalDatetxtbox.Text));
cmd.Parameters.AddWithValue("#name", nametxtbox.Text);
cmd.Parameters.AddWithValue("#age", int.Parse(agetxtbox.Text));
cmd.Parameters.AddWithValue("#address", addresstxtbox.Text);
cmd.Parameters.AddWithValue("#birthday", int.Parse(birthdaytxtbox.Text));
cmd.Parameters.AddWithValue("#email", (emailtxtbox.Text));
cmd.Parameters.AddWithValue("#home/office number", int.Parse(homeofficetxtbox.Text));
cmd.Parameters.AddWithValue("#mode of payment", (modeofpaymenttxtbox.Text));
cmd.Parameters.AddWithValue("#amount", int.Parse(amounttxtbox.Text));
cmd.ExecuteNonQuery();
connection.Close();
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
MessageBox.Show("Record inserted successfully!");
}
}
}
As a newbie, getting the pieces working first, then applying to the user interface I would apply second. I will try to summarize each piece. First your connection itself looked strange as others have pointed out. I would try to first make sure the connection itself works before applying any attempt at sql insert/update/delete going on. So you might try
SqlConnection connection = new SqlConnection(
#"Data Source (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;
Integrated Security=True;
Connect Timeout=30" );
private void TestConnect()
{
if( connection.Open() )
// great, you have a good connection
connection.Close();
else
// message to yourself why a failed connection and fix it...
}
Once you know your connection is good, then on to your sql-insert. Having good column names is important. Dont try to be fancy with human readable with spaces types of column names, just causes headaches. Use simple and direct as others have pointed out in prior comments. Also, when parameterizing, I have tried to always slightly alter the insert/update/delete parameters with a "p" prefix indicating the PARAMETER FOR the column, such as
insert into SomeTable ( oneColumn, secondCol ) values ( #pOneColumn, #pSecondCol )
just to avoid bad confusion. If an error comes out via "oneColumn" vs "pOneColumn" in the message, you KNOW which thing is at fault. The column itself does not work, or the specific parameter/value being supplied.
Next, readability of your SQL statements, especially as they get longer. Use spaces and I typically use a leading "#" before the quoted sql command to allow for line continuations as I edited your previous answer. So the same above insert would be written more like
var cmd = new SqlCommand(
#"insert into SomeTable
( oneColumn,
secondCol
)
values
( #pOneColumn,
#pSecondCol
)", connection );
So if you ever needed to add additional columns (or remove), you can see the paired set of insert columns vs parameters much easier.
Now the testing. Don't try to work off some user-entered values, put in known VALID values so you dont have to worry about user entered values. Get the command to WORK, then pull values from interface later. (continuing from above sample)
cmd.Parameters.AddWithValue("#pOneColumn", 17 );
cmd.Parameters.AddWithValue("#pSecondCol", "some Text");
Then try to execute that and make sure IT works. Once it does, THEN start pulling from your user interface
cmd.Parameters.AddWithValue("#pOneColumn", int.Parse( yourTextControl.Text ));
cmd.Parameters.AddWithValue("#pSecondCol", anotherTextControl.Text );
Find your mistakes BEFORE you let any human interaction get into and screw-up the rest of what you think SHOULD work.
Note, if you make public properties to your view models such as
public int someAge {get; set;}
and then set the bindings of the data entry control in the screen to this someAge property, it will only allow a numeric entry to be entered and will otherwise have a value of zero if someone tries to put in text. Similarly if you are dealing with dates, and if date/time, always use datetime fields for querying purposes vs formatted date as a text field. You will thank yourself in the future when querying for things within date range periods. HTH
Finally,try to avoid using AddWithValue. Instead, properly identify the expected data type as described in the linked article. I just left original context to your code for testing and debug researching purposes.
This would be the possible answer on your question, what I have done here, first I changed your connection string by removing AttachDbFilename attribute, and replace that by adding of Initial Catalog attribute where I set the name of your database.
Next thing, I declared variables where the values from textboxes will be stored, these values of variables will be our parameters, this is not necessary to do, it is just my own style, you can keep as you done.
I have seen also, that you are not using try/catch/finally block and you are closing the connection in the same part of code where you opening the connection, and maybe that is the reason why your values are not being stored into the table, so I decided to round your code within that block. If you don't know what is try/catch/finally block you can read the documentation here . We are opening the connection and do all operations on database in try block, in catch block we are catching all errors that might be caused in our application and in finally we are closing the connection. You will also notice that I created additional check, where I checking the result of ExecuteNonQuery() method, and if result of ExecuteNonQuery method is equals to 1 - records is inserted successfully, otherwise it fails.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=EaglePlannersDataBase;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void InsertButton_Click(object sender, EventArgs e)
{
int policyNumber = Convert.ToInt32(policyNumbertxtbox.Text);
string planType = planTypetxtbox.Text;
int renewalDate = Convert.ToInt32(renewalDatetxtbox.Text);
string name = nametxtbox.Text;
int age = Convert.ToInt32(agetxtbox.Text);
string address = addresstxtbox.Text;
int birthday = Convert.ToInt32(birthdaytxtbox.Text);
string email = emailtxtbox.Text;
int homeOfficeNumber = Convert.ToInt32(homeofficetxtbox.Text);
string modeOfPayment = modeofpaymenttxtbox.Text;
int amount = Convert.ToInt32(amounttxtbox.Text);
try
{
connection.Open();
SqlCommand cmd = new SqlCommand("Insert Into tbl1 (PolicyNumber,planType,renewalDate,name,age,address,birthday,email,homeOfficeNumber,modeOfPayment,amount) values (#PolicyNumber,#planType,#renewalDate,#name,#age,#address,#birthday,#email,#homeOfficeNumber,#modeOfPayment,#amount)", connection);
cmd.Parameters.AddWithValue("#PolicyNumber",policyNumber);
cmd.Parameters.AddWithValue("#planType",planType);
cmd.Parameters.AddWithValue("#renewalDate",renewalDate);
cmd.Parameters.AddWithValue("#name",name);
cmd.Parameters.AddWithValue("#age",age);
cmd.Parameters.AddWithValue("#address",address);
cmd.Parameters.AddWithValue("#birthday",birthday);
cmd.Parameters.AddWithValue("#email",email);
cmd.Parameters.AddWithValue("#homeOfficeNumber",homeOfficeNumber);
cmd.Parameters.AddWithValue("#modeOfPayment",modeOfPayment);
cmd.Parameters.AddWithValue("#amount",amount);
int result = cmd.ExecuteNonQuery();
if(result == 1)
{
MessageBox.Show("Record Inserted Successfully!");
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
}
else
{
MessageBox.Show("Something went wrong!");
}
}
catch(SqlException ex)
{
MessageBox.Show("We have found error with operation on database: " + ex.Message);
}
catch(Exception ex)
{
MessageBox.Show("We have found error in your code: " + ex.Message);
}
finally
{
connection.Close();
}
}
}
}
here's my new code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void InsertButton_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = new SqlCommand(
#"Insert Into tbl1
( PolicyNumber,
planType,
renewalDate,
name,
age,
address,
birthday,
email,
homeOfficeNumber,
modeOfPayment,
amount )
values
( #PolicyNumber,
#planType,
#renewalDate,
#name,
#age,
#address,
#birthday,
#email,
#homeOfficeNumber,
#modeOfPayment,
#amount )", connection);
cmd.Parameters.AddWithValue("#PolicyNumber", int.Parse(policyNumbertxtbox.Text));
cmd.Parameters.AddWithValue("#planType", planTypetxtbox.Text);
cmd.Parameters.AddWithValue("#renewalDate", int.Parse(renewalDatetxtbox.Text));
cmd.Parameters.AddWithValue("#name", nametxtbox.Text);
cmd.Parameters.AddWithValue("#age", int.Parse(agetxtbox.Text));
cmd.Parameters.AddWithValue("#address", addresstxtbox.Text);
cmd.Parameters.AddWithValue("#birthday", int.Parse(birthdaytxtbox.Text));
cmd.Parameters.AddWithValue("#email", (emailtxtbox.Text));
cmd.Parameters.AddWithValue("#homeOfficeNumber", int.Parse(homeofficetxtbox.Text));
cmd.Parameters.AddWithValue("#modeOfPayment", (modeofpaymenttxtbox.Text));
cmd.Parameters.AddWithValue("#amount", int.Parse(amounttxtbox.Text));
cmd.ExecuteNonQuery();
connection.Close();
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
MessageBox.Show("Record Inserted Successfully!");
}
}
}
here's my database

memory low error after caling database class method

I have bellow class in my project that can help me to run SQL commands directly. in my computer it works fine. but when I published to web server after about 5 or 6 times that I called in page I got memory low error. that error cleaned after about 20 minutes. but it happens again and again.
using System;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Data;
using System.Data.Linq;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Globalization;
public class FirstClass
{
SqlConnection con;
public SqlCommand cmd;
DataTable dt;
SqlDataAdapter da;
public FirstClass()
{
con = new SqlConnection(ConfigurationManager.ConnectionStrings["WebSiteConnectionString"].ConnectionString);
cmd = new SqlCommand();
dt = new DataTable();
cmd.Connection = con;
da = new SqlDataAdapter(cmd);
}
public DataTable dbSelect(string sql)
{
DataTable dttt = new DataTable();
try
{
cmd.CommandText = sql;
con.Open();
da.Fill(dt);
con.Close();
return dt;
}
catch
{
return dttt;
}
}
public void exeSp(string spName)
{
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = spName;
cmd.ExecuteNonQuery();
con.Close();
}
public void exeSqlCmd(string sql)
{
try
{
cmd.CommandText = sql;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch { }
}
}
This mostly happens when I use the first method. Of course, the number of records that are fetched is also important. The higher the number of records fetched, the faster the memory shortage error occurs. But after about 20 minutes, all the bugs will be fixed automatically and I can run the code again. But unfortunately I get the same error message again. Please help.
The code in the question has several issues. I will only explicitly mention some issues related to use of classes in System.Data.SqlClient, and not mention general issues, though the code shown here solves many of the general issues, but not all.
The classes SqlConnection, SqlCommand, SqlDataAdapter, SqlDataReader and so on, are lightweight, and should be created and released in the innermost scope possible. There is nothing to gain by trying to reuse these by holding on to them across queries. They also need to be properly managed with regards to memory use as well as resource use, not only when execution follows the success path, but also when errors arise. This can be achieved as follows.
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public static class FirstClass
{
private static string connectionString =
ConfigurationManager.ConnectionStrings["WebSiteConnectionString"].ConnectionString;
private static SqlConnection GetConnection()
{
return new SqlConnection(connectionString);
}
public static DataTable DbSelect(string sql)
{
using (var con = GetConnection())
{
using (var cmd = new SqlCommand(sql, con))
{
using (var adapter = new SqlDataAdapter(cmd))
{
try
{
DataTable result = new DataTable();
adapter.Fill(result);
return result;
}
catch
{
return null;
}
}
}
}
}
public static void ExeSp(string spName)
{
using (var con = GetConnection())
{
using (var cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = spName;
cmd.ExecuteNonQuery();
}
}
}
public static void ExeSqlCmd(string sql)
{
using (var con = GetConnection())
{
using (var cmd = new SqlCommand(sql, con))
{
try
{
cmd.ExecuteNonQuery();
}
catch
{
}
}
}
}
}
The class has been made static, which makes sure all memory and resource management now takes place within each single method. We no longer rely on knowing how the class itself is used elsewhere in order to understand how things work. Within the methods, use of using now clearly tells us how resources, including memory, is allocated and deallocated. We can see that everything is properly disposed, so that there is no longer any way that any resource can be lying around between database calls, whether there's success or error in calls. In the DbSelect method, the DataTable is created as close to its point of use as possible, so that we easily see what it's doing.
It is not clear what the intention of having one local and one class level DataTable was in the original code, which returns one or the other - likely just a temporary glitch while experimenting - but in this new version the caller is responsible for disposing the returned result after use. An alternative is possibly to have the caller offer a DataTable to fill in, if that's easier for the caller. If so, just clear the table before filling.
When it comes to error handling, it can be improved, but I won't go into that.
This code compiles, but I have not verified that it actually works. My intention is to show how to organize these kinds of database calls in general, and you can work on fixing any error I may have overlooked from there on.

C# variable in a MySql query isn't recognized

I have an int variable in my C# code and I'm trying to use it in a MySql query.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data;
using MySql.Data.MySqlClient;
namespace projeV1
{
public partial class ProjeDetay : Form
{
public ProjeDetay()
{
InitializeComponent();
}
private void ProjeDetay_Load(object sender, EventArgs e)
{
int satir_projem = Projeler.satir_proje;
string connectionString = "Server = localhost; Port = ...; Database = ...; Uid = root; Pwd = ...; Allow User Variables=True";
MySqlConnection databaseConnection = new MySqlConnection(connectionString);
MySqlCommand command;
databaseConnection.Open();
command = databaseConnection.CreateCommand();
string myQuery = "select projeAdi from projeler where projeID = #satir_projem";
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(myQuery, databaseConnection);
command.Parameters.Add("#satir_projem", MySqlDbType.Int32).Value = satir_projem;
DataSet DS = new DataSet();
dataAdapter.Fill(DS);
dataGridView_ProjeDetay.DataSource = DS.Tables[0];
MessageBox.Show(Projeler.satir_proje.ToString());
MessageBox.Show(satir_projem.ToString());
}
}
}
(Sorry if it looks like a mess in regard to coding but I'm new at this ^^)
MessageBox windows show the variables' values correctly, so there's no problem with the variable. And when I replace#satir_projem from the query string with a number like "2" (see the example below), for example, the result is correct, but when I use #satir_projem in the query, it doesn't work. I can't see what I'm doing wrong.
Example query string:
"select projeAdi from projeler where projeID = 2"
P.S 1: Originally I'm trying to get the index of the selected row (which is the variable called Projeler.satir_proje) in a DataGridView used in a form called "Projeler" and in another form (which is called ProjeDetay), assigning that index value into another variable called "satir_projem" and use this value to get the related data from my database and put that data in another DataGridView located in my second form (which is called dataGridView_ProjeDetay).
P.S 2: I've made a lot of research about this problem and tried many of the solutions I encountered along the way; however, none of them worked for me. So, here I am :)
Thanks in advance.
You are setting parameter for command that is not used.
Instead you should use DataAdapter.SelectCommand
dataAdapter.SelectCommand.Parameters.Add(...)
MySqlConnection databaseConnection = new MySqlConnection(connectionString);
MySqlCommand command;
string myQuery = "select projeAdi from projeler where projeID = #satir_projem";
databaseConnection.Open();
command = new MySqlCommand(myQuery, databaseConnection);
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(command);
Just want to elaborate, why #Onur_Saatcioglu's code is throwing error.
you are adding #satir_projem to command but the parameter thus added to command is not being passed to dataadapter which serves as a bridge between a DataSet and SQL Server for retrieving and saving data.
Hence you can
1) As Lester told, create command like
command = new MySqlCommand(myQuery, databaseConnection);
and pass the command to DataAdapter
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(command);
2) As #Pablo_notPicasso said, if you are using
dataAdapter.SelectCommand.Parameters.AddWithValue("#satir_projem", satir_projem);
then "command" does not make sense, you can just delete it.

Calling class from code behind

I am still new to ASP.net and I'm learning how to call classes. I've looked around for tutorials, but not all are specific to ASP.net 4.0 so I'm not sure if I should apply them.
Right now, I am trying to connect to my SQL database. My webconfig file has been set up with the connectionstring "dbConnectionString" and is working properly when I've tested it with GridViews. What I'd like to do now is access the database from code behind.
I've seen some ways to accomplish this, but I'd like the most efficient, resuable way. I've tried to adopt the answer listed here: How to create sql connection with c# code behind, access the sql server then conditionally redirect? however, I'm getting an error.
I am doing this with C# as a website, not a web application. Here is my code behind for Login.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SqlComm; // Is this how I connect to my class from this page????
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//no code written yet
}
}
}
My class in the App_Code folder, file name SQLComm.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Web;
/// <summary>
/// SQL Query class
/// </summary>
public class SqlComm
{
// Connection string
static string DatabaseConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConnectionString"].ConnectionString;
// Execute sql command with no value to return
public static void SqlExecute(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
}
}
// Execute SQL query and return a value
public static object SqlReturn(string sql)
{
using (SqlConnection conn = new SqlConnection(PjSql.dbcs()))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
object result = (object)cmd.ExecuteScalar();
return result;
}
}
// Retrieve an entire table or part of it
public static DataTable SqlDataTable(string sql)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Connection.Open();
DataTable TempTable = new DataTable();
TempTable.Load(cmd.ExecuteReader());
return TempTable;
}
}
// Execute a stored procedure with 1 parameter
// Returning a value or just executing with no returns
public static object SqlStoredProcedure1Param(string StoredProcedure, string PrmName1, object Param1)
{
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(StoredProcedure, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter(PrmName1, Param1.ToString()));
cmd.Connection.Open();
object obj = new object();
obj = cmd.ExecuteScalar();
return obj;
}
}
}
As you can see, I haven't written any code to actually use the class yet, but the "using SQLComm;" line itself is giving me this error:
Compiler Error Message: CS0246: The type or namespace name 'SqlComm' could not be found (are you missing a using directive or an assembly reference?)
As I'm still new, I'm unsure where to go from here. I seem to have included everything contained in the answer on the page I linked above. What else and I missing?
Edit: I read this post regarding a similar issue: asp.NET 2.0 Web Site Can't Access Classes in App_Code
Could this be because I am doing a website and not a web application, so the App_Code folder is being handled differently when I FTP the files over?
using SQLComm means you want to use the namespace SqlComm, which doesn't exist. I think what you want is (somewhere in your codebehind):
DataTable dt = SqlComm.SqlDataTable(...) // call one of the static methods.
You can call it directly.
Given your class has static methods only you'll call it like this:
SqlComm.SqlReturn("select * from table");
So I believe I figured it out. I had my App_Code folder within the subdirectory of my Aspx website, instead of in the root of the server. I moved the folder to the root and now it's working.
I'd be interested in hearing any answers to my edit to my original post though. Since I'm doing this as a website instead of a web application, are there any other issues I will need to keep in mind regarding using classes like this or other issues? I've looked around but haven't seen many differences.
Thanks to everyone for you help!

removing form from c# code?

I'm extremely new to C# and programming anything except for SQL. I've gotten the below code to happen on a Form and on a button click. If I wanted to just make this run on open, how would I do that? I'm very new to C# as you can tell (just started today learning it but its pretty exciting!)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
using Oracle.DataAccess.Types;
namespace OraTrigger
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string oradb = "Data Source=OMP1;User Id=user;Password=pass;";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT cast(Count(*) as varchar(20)) as trig FROM ZDMSN.TRIGGER_TEST";
//cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
int cnt;
if (int.TryParse(dr.GetString(0), out cnt))
{
if (cnt > 0)
{
System.Diagnostics.Process.Start(#"C:\testfile.bat");
}
}
cmd.CommandText = "TRUNCATE TABLE ZDMSN.TRIGGER_TEST";
conn.Dispose();
}
}
}
If you need to run your code as a scheduled task then a command line application is more suitable.
Just create a new project and select Console Application.
Then move all of your button click code inside the Main method written for you by the Visual Studio IDE.
Rembember to set the references to the Oracle ODP.NET library and import the relevant using statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
using Oracle.DataAccess.Types;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string oradb = "Data Source=OMP1;User Id=user;Password=pass;";
using(OracleConnection conn = new OracleConnection(oradb))
using(OracleCommand cmd = new OracleCommand("SELECT Count(*) as trig FROM ZDMSN.TRIGGER_TEST", conn))
{
conn.Open();
int cnt = (int)cmd.ExecuteScalar();
if (cnt > 0)
{
System.Diagnostics.Process.Start(#"C:\testfile.bat");
cmd.CommandText = "TRUNCATE TABLE ZDMSN.TRIGGER_TEST";
cmd.ExecuteNonQuery();
}
}
}
}
}
I have also revised your code to get a single value from the database. For this case is enough to use the Command.ExecuteScalar method that returns the first column of the first row obtained from your sql command text. Because the count(*) should Always return a single row you could easily cast the return value of ExecuteScalar to your record count variable.
EDIT I have added the logic to TRUNCATE the table involved. Please pay attention that you should use the code provided here. Your code will probably fail because you have an open DataReader and when a DataReader is open you cannot execute other commands (This is true for SqlServer without Multiple Active Result Sets enabled, I really don't know if this rules applies also to the Oracle NET Provider)
Subscribe to Shown or Load event of form and move your code to that event handler.
Form.Shown Event Occurs whenever the form is first displayed.
Form.Load Event Occurs before a form is displayed for the first time.
Also I suggest to extract your code to some Data Access related class, or at least to separate method. And call that method from event handler.

Categories

Resources