How to pass dataset through query - c#

I need to get a database values to the p_cat combo box .....but i cannot pass the dataset inside the query..
class Datatbl_Class1
{
DataSet ds = new DataSet();
public DataSet filldata(string q)
{
string myconnection = "datasource=localhost;port=3306;username = root; password = 12345V";
MySqlConnection con = new MySqlConnection(myconnection);
MySqlCommand cmd = new MySqlCommand(q, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(ds);
return ds;
}
}
Select_int_Class1 s4 = new Select_int_Class1();
string q = "SELECT Sup_ID FROM gtec_computer.supplier WHERE Sup_Name='" +p_cmb_sup.Text+ "'";
string ww = "Sup_ID";
int t = s4.select_val_int(q, ww);
DataSet n = new DataSet();
Datatbl_Class1 dt = new Datatbl_Class1();
string Query = "SELECT Cat_ID FROM gtec_computer.supplier_detail WHERE Sup_Id="+t+" ";
n = dt.filldata(Query)
DataSet ds = new DataSet();
string myconnection = "datasource=localhost;port=3306;username = root; password = 12345V";
MySqlConnection con = new MySqlConnection(myconnection);
string q1 = "SELECT cat_Name FROM gtec_computer.category WHERE Cat_ID= " + n + " ";
MySqlCommand cmd = new MySqlCommand(q1, con);
MySqlDataAdapter da1 = new MySqlDataAdapter(cmd);
da1.Fill(ds);
p_cat.DataSource = ds;

You should be able to via parameter to the function call in the class... However, by building your command strings, you would be wide open for SQL-injection. Look into parameterized queries. Now, back to your original code and an alternative implementation...
class Datatbl_Class1
{
public DataSet filldata(string q )
{
string myconnection = "datasource=localhost;port=3306;username = root; password = 12345V";
MySqlConnection con = new MySqlConnection(myconnection);
MySqlCommand cmd = new MySqlCommand(q, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ReturnThisOne = new DataSet();
da.Fill(ReturnThisOne);
return ReturnThisOne;
}
}
Just dont make the "ds" as a property of the class. Just create a new instance of a dataset within your method. It will be a pointer anyhow. Fill that and return the pointer to the calling source as you already are doing with your "n = dt.filldata(Query)". Yes, the function is no longer using the data table, but since it's reference is being returned, then the "n" location that is calling it will retain it. It won't get released to garbage collection until the function that "n" is in gets released.
Again, look into parameters to prevent sql-injection. But this should get you going.

Related

C# Parameterized query - parameters not being replaced with set value

I'm passing a query and parameter from a WinForm to a database class. The
The code on the Form looks like this:
string selectedComp = "CPSI";
string catsQuery = "SELECT id, category, old_value, old_desc, new_value, new_desc, reference1, reference2 FROM masterfiles.xref WHERE company_name = '#company' ORDER BY category, old_value";
Db categoriesData = new Db();
dgvCategories.DataSource = categoriesData.GetData(catsQuery, selectedComp);
And in my database class my code to populate the datatable/set is this:
public DataTable GetData(string selectQuery, string selectedComp)
{
NpgsqlConnection conn = new NpgsqlConnection(connString);
DataSet ds = new DataSet();
NpgsqlCommand cmd = new NpgsqlCommand(selectQuery, conn);
cmd.Parameters.Add(new NpgsqlParameter("#company", selectedComp));
//cmd.Parameters.AddWithValue("#company", selectedComp);
//cmd.Parameters.Add("#company", NpgsqlDbType.Text);
//cmd.Parameters["#company"].Value = selectedComp;
try
{
conn.Open();
NpgsqlDataAdapter da = new NpgsqlDataAdapter(selectQuery, conn);
conn.Close();
da.Fill(ds);
return ds.Tables[0];
}
}
But putting a breakpoint at NpgsqlDataAdapter da = new NpgsqlDataAdapter(selectQuery, conn);, selecctQuery hasn't changed - the '#company' is still in the query.
What am I missing?
The root problem is that you're passing the query to the data adapter instead of the command. Change
NpgsqlDataAdapter da = new NpgsqlDataAdapter(selectQuery, conn);
to
NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd);
I would also use using to dispose of all objects, and don't close the connection until the dataset is filled:
using(NpgsqlConnection conn = new NpgsqlConnection(connString))
using(NpgsqlCommand cmd = new NpgsqlCommand(selectQuery, conn))
{
cmd.Parameters.Add(new NpgsqlParameter("company", selectedComp));
conn.Open();
using(NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
da.Fill(ds);
}
conn.Close();
return ds.Tables[0];
}

How to Reuse Logic Without Copy/Pasting Blocks of Code - C#

My project reuses the code below multiple times with only a few variables changing. I've noted the values that change with e.g. ***value***.
if (comboBox1.Text == ***"Most recent first"***)
{
string dgvconn = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\n0740572\Projects\CW\CW\bin\Debug\Database1.mdf;Integrated Security=True";
string sql = "select * from Records where UserID = #userID Order By ***Date Desc***";
SqlConnection connection = new SqlConnection(dgvconn);
SqlDataAdapter dataadapter = new SqlDataAdapter(sql, connection);
dataadapter.SelectCommand.Parameters.AddWithValue("#userID", currentUserID);
DataSet ds = new DataSet();
connection.Open();
dataadapter.Fill(ds, "Records");
connection.Close();
recordsDataGridView.DataSource = ds;
recordsDataGridView.DataMember = "Records";
}
How can I use this same logic, with different values, without copying and pasting the if statement multiple times?
Sounds to me you want something like:
private void foo(string matchText, string sortBy) {
if (comboBox1.Text == matchText)
{
string dgvconn = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\n0740572\Projects\CW\CW\bin\Debug\Database1.mdf;Integrated Security=True";
string sql = "select * from Records where UserID = #userID Order By " + sortBy;
SqlConnection connection = new SqlConnection(dgvconn);
SqlDataAdapter dataadapter = new SqlDataAdapter(sql, connection);
dataadapter.SelectCommand.Parameters.AddWithValue("#userID", currentUserID);
DataSet ds = new DataSet();
connection.Open();
dataadapter.Fill(ds, "Records");
connection.Close();
recordsDataGridView.DataSource = ds;
recordsDataGridView.DataMember = "Records";
}
}//foo
//Call the method
foo("Most recent first", "Date DESC");
foo("Most recent last", "Date");
foo("By Username", "User");

SqlDataAdapter handle error - object is not created

I have this error:
Invalid object name 'sap.AfdelingsrapportACTUAL'.
Which is because this table is not created yet.
I need to implement a check in my SqlDataAdapter - so if is null or doesnt get anything it moves on. But i really doesnt know how to.
I think it should be around my SqlDataAdapter but i could be wrong
Code
DataTable sqldt = new DataTable();
string sqlQuery = #"Select * from " + table;
SqlConnection sqlcon = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sqlQuery, sqlcon);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(sqldt);
}
What i think it should look like:
public static bool CompareDataTables(DataTable dt, string table, string connectionString)
{
DataTable sqldt = new DataTable();
string sqlQuery = #"Select * from " + table;
SqlConnection sqlcon = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(sqlQuery, sqlcon);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
if (da == "doesnt have any table")
{
return true;
}
else
{
da.Fill(sqldt);
}
}
int sqlCols = sqldt.Columns.Count;
int excelCols = dt.Columns.Count;
if (excelCols == sqlCols)
{
return false;
}
else return true;
}
One way would be first check for the existence of the data table.
follow the sample given here:
Check if table exists in SQL Server

fill gridView with return dataset

how to pass ds from sql class to form class
in my form class
sqlCls floor = new sqlCls();
floor.getByFloor(floorNo);
reportFormDataGridView.DataSource = ds.Tables[0]; ******
in sql class . floor method
public DataSet getByFloor(int floorNo)
{
DataSet ds = new DataSet();
SqlConnection conn = connectionCls.openConnection();
SqlCommand com = new SqlCommand("select * from table where floorsNo = " + floorNo, conn);
SqlDataAdapter SE_ADAPTAR = new SqlDataAdapter(com);
SE_ADAPTAR.Fill(ds);
conn.Close();
return ds;
}
GridViews can take a DataSet as the DataSource just fine, no need to use a table.
Just do this:
sqlCls floor = new sqlCls();
var ds = floor.getByFloor(floorNo);
reportFormDataGridView.DataSource = ds;
You have a SQL Injection vulnerability in your code. Please consider using SQL parameters instead of unsanitized input.
So in your case it would be:
public DataSet getByFloor(int floorNo)
{
DataSet ds = new DataSet();
SqlConnection conn = connectionCls.openConnection();
SqlCommand com = new SqlCommand("select * from table where floorsNo = #floorsNo", conn);
com.Parameters.AddWithValue("#floorsNo", floorNo);
using(SqlDataAdapter SE_ADAPTAR = new SqlDataAdapter(com))
{
SE_ADAPTAR.Fill(ds);
conn.Close();
}
return ds;
}
SqlDataAdapter implements the IDisposable interface so you can wrap it in a using block to automatically dispose of resources when execution flow leaves the scope.

using WHERE in my Insert query statement

string conString = #"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=C:\Users\user\Documents\Visual Studio 2010\Projects\Timetable\Timetable\bin\Debug\timetabledata.accdb";
//create the database query
string query = "SELECT * FROM relation";
OleDbConnection conn = new OleDbConnection(conString);
conn.Open();
// create the DataSet
DataSet ds = new DataSet();
// create the adapter and fill the DataSet
OleDbDataAdapter adapter;
adapter = new OleDbDataAdapter(query, conn);
adapter.Fill(ds);
int f = ds.Tables[0].Rows.Count;
int i;
for (i = 0; i < f; i++)
{
// create the database query
string query1 = "SELECT * FROM [time] Where classid= '"+
ds.Tables[0].Rows[i].ItemArray[2]+"'";
DataSet ds1 = new DataSet();
OleDbDataAdapter adapter1;
adapter1 = new OleDbDataAdapter(query1, conn);
adapter1.Fill(ds1);
MessageBox.Show(ds1.Tables[0].Rows[0].ItemArray[0].ToString());
}
the result that i get not true in message box that i want the id of all rows having the same classid but in message box that i use just to verification before o continue i see the id of time table without be consider where
Shouldn't this part be changed from...
string query1 = "SELECT * FROM [time] Where classid+ '"+
ds.Tables[0].Rows[i].ItemArray[2]+"'";
to...
string query1 = "SELECT * FROM [time] Where classid = '"+
ds.Tables[0].Rows[i].ItemArray[2]+"'";
You seem to be using a plus symbol (+) instead of equals (=).
Give this a shot:
public DataSet GetRelations()
{
using (var connection = new OleDbConnection(ConnectionString))
{
connection.Open();
using (var adapter = new OleDbDataAdapter("SELECT * FROM [relation]", connection))
{
var results = new DataSet();
adapter.Fill(results);
return results;
}
}
}
public DataSet GetTimeResults()
{
DataSet dsRelations = GetRelations();
var dsResults = new DataSet();
using (var connection = new OleDbConnection(ConnectionString))
{
connection.Open();
foreach (DataRow row in dsRelations.Tables[0].Rows)
{
using (var command = new OleDbCommand("SELECT * FROM [time] Where classid = ?", connection))
{
// not entirey sure what the value of row.ItemArray[2] is ?
command.Parameters.Add(row.ItemArray[2]);
using (var adapter = new OleDbDataAdapter(command))
{
adapter.Fill(dsResults);
}
}
}
}
return dsResults;
}
Just invoke it and use it as you see fit:
public void Test()
{
DataSet dsTimeResults = GetTimeResults();
// Do whatever you need with the results
}

Categories

Resources