Problem in populating the GridView in ASP.NET(C#) - c#

I'm trying to populate a Gridview with results from loop. But I'm getting only last result in the loop.
I think GridView is being overwritten on every time the for loop is being executed.
Can you people help me to remove this problem please.
for (int j = 0; j < i; j++)
{
Label1.Text += fipath[j];
Label1.Text += "-------------";
SqlConnection conn = new SqlConnection("Server=ILLUMINATI;" + "Database=DB;Integrated Security= true");
SqlCommand comm = new SqlCommand("Select * from FileUpload where UploadedBy='" + NAME + "' AND FilePath='" + fipath[j] + "'", conn);
try
{
conn.Open();
SqlDataReader rdr = comm.ExecuteReader();
if (Role.Equals("admin"))
{
GridView1.DataSource = rdr;
GridView1.DataBind();
}
rdr.Close();
}
catch
{
conn.Close();
}
}

There is more than one problem with this code:
seems like if Role== "admin" you don't need to query db at all
DataSource of the grid is overridden on every loop iteration, this is why you see only the last value.
use parameters for SqlCommand to prevent SQL injection.
don't run string concatenation in the loop. Use StringBuilder instead
use using for your connection. The code is cleaner this way.
The fix could look like this:
if (Role != "admin")
return;
var dataTable = new DataTable();
var stringBuilder = new StringBuilder();
using (var connection = new SqlConnection("Server=ILLUMINATI;" + "Database=DB;Integrated Security= true"))
using (var command = connection.CreateCommand())
{
connection.Open();
command.CommandText = "Select * from FileUpload where UploadedBy = #UploadedBy AND FilePath = #FilePath";
command.Parameters.AddWithValue("UploadedBy", NAME);
var filPathParameter = command.Parameters.Add("FilePath", SqlDbType.VarChar);
for (int j = 0; j < i; j++)
{
stringBuilder.Append(fipath[j]);
stringBuilder.Append("-------------");
filPathParameter.Value = fipath[j];
dataTable.Load(command.ExecuteReader(), LoadOption.PreserveChanges);
}
}
Label1.Text += stringBuilder.ToString();
GridView1.DataSource = dataTable;
GridView1.DataBind();
Also, I don't know how many elements your normal loop is. If it is one or two and you have appropriate indexes in FileUpload table then it is ok to leave as is. However, if you need to do the for many times you should consider switching to a single query instead
For example:
var filePathes = string.Join(",", fipath.Select(arg => "'" + arg + "'"));
var command = "Select * from FileUpload where UploadedBy = #UploadedBy AND FilePath in (" + filePathes + ")";
This query is SQL injection prone. And has a 2100 elements limit in MS SQL.
There is more than one way to approach this. Depends on your DBMS and requirements.

Use the in clause in SQL Query and pass the list of ID's in FilePath
SqlCommand comm = new SqlCommand("Select * from FileUpload where UploadedBy='" + NAME
+ "' AND FilePath in (" + listOfIDs + ")", conn);
Check out these URLs that are related to the use of in clause.
Techniques for In-Clause and SQL Server
Parameterizing a SQL IN clause?

Create a list or BindingSource outside the loop, bind that to your gridview and then add all records to that list or source.
The problem with your current approach is that you are overwriting the records pulled from the database with a new datasource each time, so as you stated, only the last one is "set", and the older assignments are disposed of.

Related

Selecting and retrieving multiple cells in different rows

I'm trying to retrieve multiple cells in different rows where the correct owner exists, but I'm only being able to retrieve the first match and it stops there, I've tried using it with a for, but I don't think .ExecuteScalar() is the way to do this. Maybe I'm just stupid and doing it completely wrong.
Code:
checkPlayerName = API.getPlayerName(player);
string checkOwnedCars = "SELECT COUNT(*) FROM [carOwners] WHERE Owner='" + checkPlayerName + "'";
con.Open();
SqlCommand checkCarsCount = new SqlCommand(checkOwnedCars, con);
int carsCountToVar = Convert.ToInt32(checkCarsCount.ExecuteScalar());
con.Close();
for (int i = 0; i < carsCountToVar; i++)
{
string displayCars = "SELECT LP FROM [carOwners] WHERE Owner='" + checkPlayerName + "'";
con.Open();
SqlCommand displayCarsCMD = new SqlCommand(displayCars, con);
string displayCarsToVar = displayCarsCMD.ExecuteReader().ToString();
API.sendChatMessageToPlayer(player, "Owned Vehicle: " + displayCarsToVar.ToString());
con.Close();
}
Table
For example, LP on 2nd and 3rd row are the ones that I want to store since both belong to the same owner, yet only first cell data (1337) is displaying.
You are not iterating the results you are getting from query.
Plus always use Parameterized queries to prevent SQL Injection Attacks
SqlCommand command = new SqlCommand("SELECT LP FROM [carOwners] WHERE Owner=#checkPlayerName", con);
command.Parameters.AddWithValue("#checkPlayerName",checkPlayerName);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}",reader["id"]));
//API.sendChatMessageToPlayer(player, "Owned Vehicle: " + reader["id"].ToString());
}
}
conn.Close();

Add multiple SQL values with same parameterized query?

I'm fairly new to SQL and trying to figure out the best way to add some predefined data. I figured out from searching around here that I should used a parameterized command to avoid a sql injection attack which isn't a huge concern in this case but I would like to avoid the possibility and learn to do it right... Anyway here is the code I have right now:
using (SqlTransaction trans = connection.BeginTransaction())
{
foreach (IEnumerable<string> row in table.RowData)
{
using (SqlCommand sql = new SqlCommand("INSERT INTO " + table.Title
+ " (" + string.Join(", ", table.Headers)
+ ") VALUES (" + string.Join(", ", table.Headers.Select(x => "#" + x)) + ");", connection, trans))
{
for (int i = 0; i < table.Headers.Count(); i++)
{
if (string.IsNullOrEmpty(row.ElementAt(i)))
{ sql.Parameters.AddWithValue("#" + table.Headers.ElementAt(i), DBNull.Value); }
else
{ sql.Parameters.AddWithValue("#" + table.Headers.ElementAt(i), row.ElementAt(i)); }
}
sql.ExecuteNonQuery();
}
}
trans.Commit();
}
This seems to work and all the data gets in there but it 'feels' inefficient to me. I'm wrapping it in a transaction so there is only one commit, but it's creating the parameters every time and just setting different values for each row.
Is there a way to make this use the same parameters but just set different values per row? Or is this the best way to do this and I should not worry about it?
Thanks in advance for any help you can give.
We can do what you want by parsing the headers into parameters in a pre-processing step. I have also removed the explicit transaction because every single insert already gets an implicit transaction by default (why pay the performance penalty of two transactions?).
using (var command = new SqlCommand()) {
command.CommandText =
"INSERT INTO " + table.Title + " ("
+ string.Join(", ", table.Headers)
+ ") VALUES ("
+ string.Join(", ", table.Headers.Select(x => "#" + x))
+ ");";
command.Connection = connection;
foreach (var header in table.Headers) {
/*
Add all parameters as strings. One could choose to infer the
data types by inspecting the first N rows or by using some sort
of specification to map the types from A to B.
*/
command.Parameters.Add("#" + header, typeof(string));
}
foreach (var row in table.RowData) {
for (var i = 0; i < table.Headers.Count(); i++) {
if (!string.IsNullOrEmpty(row.ElementAt(i))) {
command.Parameters["#" + table.Headers.ElementAt(i)].Value = row.ElementAt(i);
}
else {
command.Parameters["#" + table.Headers.ElementAt(i)].Value = DBNull.Value;
}
}
command.ExecuteNonQuery();
}
}
this is my example of insert that works for me
private void insertWordCount(string songId, string wordId, int wordCount)
{
string query = "insert into songs_words_conn values(#wordId,#songId,#wordCount)";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#wordId", wordId);
cmd.Parameters.AddWithValue("#songId", songId);
cmd.Parameters.AddWithValue("#wordCount", wordCount);
cmd.ExecuteNonQuery();
}
Yes, you can be much more effecient by reusing SqlParameter objects. Here is some pseudo code:
const string sql = "INSERT INTO table1 (column1) VALUES (#p0)";
using (var sqlCommand = new SqlCommand(sql, connection, transaction))
{
var param1 = sqlCommand.Parameters.Add("#p0", SqlDbType.Int);
foreach (var row in table)
{
param1.Value = row["value"];
sqlCommand.ExecuteNonQuery();
}
}

how to add data table values to a ms access table using c#

I got 10 tables in SQL server and I want to export those table values to a ms access database which also contains 10 tables. so is there any way to export data using c# code.
I don't want to write lots of code for each table to get data from a particular table then insert row by row to the respective access table is there any shortcut available that I can use please do let me know.
i thik this code help you.
OleDbConnection myConnection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"Database.accdb\";Persist Security Info=False;");
//command to insert each ASIN
OleDbCommand cmd = new OleDbCommand();
//command to update each column (ASIN, Retail... from CSV)
OleDbCommand cmd1 = new OleDbCommand();
//load csv data to dtCSV datatabe
DataTable dtCSV = new DataTable();
dtCSV = ds.Tables[0];
// Now we will collect data from data table and insert it into database one by one
// Initially there will be no data in database so we will insert data in first two columns
// and after that we will update data in same row for remaining columns
// The logic is simple. 'i' represents rows while 'j' represents columns
cmd.Connection = myConnection;
cmd.CommandType = CommandType.Text;
cmd1.Connection = myConnection;
cmd1.CommandType = CommandType.Text;
myConnection.Open();
for (int i = 0; i <= dtCSV.Rows.Count - 1; i++)
{
cmd.CommandText = "INSERT INTO " + lblTable.Text + "(ID, " + dtCSV.Columns[0].ColumnName.Trim() + ") VALUES (" + (i + 1) + ",'" + dtCSV.Rows[i].ItemArray.GetValue(0) + "')";
cmd.ExecuteNonQuery();
for (int j = 1; j <= dtCSV.Columns.Count - 1; j++)
{
cmd1.CommandText = "UPDATE " + lblTable.Text + " SET [" + dtCSV.Columns[j].ColumnName.Trim() + "] = '" + dtCSV.Rows[i].ItemArray.GetValue(j) + "' WHERE ID = " + (i + 1);
cmd1.ExecuteNonQuery();
}
}
myConnection.Close();
If this is a one-off operation, you should use Data Export features of SQL Server or import features of Access to perform this. They'll be simple enough for end-users who don't want to write code. Therein you simply select the database, the tables that you want to export and the destination database and everything will get exported on click of a button.
First make sure that the access table columns have the same column names and similar types. Then you can use this function which I believe is very fast and elegant.
public void AccessBulkCopy(DataTable table)
{
foreach (DataRow r in table.Rows)
r.SetAdded();
var myAdapter = new OleDbDataAdapter("SELECT * FROM " + table.TableName, _myAccessConn);
var cbr = new OleDbCommandBuilder(myAdapter);
cbr.QuotePrefix = "[";
cbr.QuoteSuffix = "]";
cbr.GetInsertCommand(true);
myAdapter.Update(table);
}
use this code
Well i got the answer. i used for loop to generate query string like below.
public void MainAccess(int _i)
{
DataTable dt = ds.Tables[_i];
string sql = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
sql = sql + "INSERT INTO "+ _tableString[_i] + " values('";
for (int j = 0; j < dt.Columns.Count; j++)
{
sql += dt.Rows[i][j].ToString().Trim();
if (j != dt.Columns.Count - 1)
{
sql += "','";
}
else
{
sql += "')";
}
}
ExecuteQuery(sql);
sql = null;
}
}

how to display count in label text?

i am having a hard time to display my count code to my label text. here is my code and please tell me how to solve this problem.
ordering_and_billing.dBase dBase = new ordering_and_billing.dBase();
var mydbconnection = new dBase.dbconnection();
string sql = "SELECT * FROM `order` WHERE eventdate='" + lbldte.Text + "'";
MySqlCommand cmd = new MySqlCommand(sql, mydbconnection.Connection);
mydbconnection.Connection.Open();
MySqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
while (rdr.Read())
{
Int32 count = (Int32)cmd.ExecuteScalar();
string disp = count.ToString();
lblcount.Text = disp;
}
}
just use count function:
string sql = "SELECT COUNT(*) FROM `order` WHERE eventdate='" + lbldte.Text + "'";
also don't use ExecuteReader, use ExecuteScalar function if you want a single value like a count value:
lblcount.Text =cmd.ExecuteScalar().toString();
You should use SELECT COUNT(*) if all you want is the record count.
string sql = "SELECT COUNT(*) FROM `order` WHERE eventdate='" + lbldte.Text + "'";
However, keep in mind that rdr.Read() reads a new row from the sql query. Every time you get a new row, you're trying to rerun the sql command (which I'm guessing crashes) and then assign the count label. So you're trying to assign the count label count times. Use this construct instead:
int count = 0;
while (rdr.Read())
{
count++;
}
lblcount.Text = count.ToString(); //only assigns to the Text property once
never mind guys i got my answer now.
ordering_and_billing.dBase dBase = new ordering_and_billing.dBase();
var mydbconnection = new dBase.dbconnection();
string sql = "SELECT * FROM `order` WHERE eventdate='" + lbldte.Text + "'";
MySqlCommand cmd = new MySqlCommand(sql, mydbconnection.Connection);
mydbconnection.Connection.Open();
MySqlDataReader rdr = cmd.ExecuteReader();
int count = 0;
while (rdr.Read())
{
count ++;
}
lblcount.Text = count.ToString();

How to Access Specific Fields of Data from Database

I am working on a inventory software in which I want to access the ProductName and Product Price by Comparing it With the ProductCode, the Data I've Already Stored in Database table named ProductLog, the Data in Product Log is:
ItemNO Productode ProductName ProductPrice
1 123 lux 58
2 321 soap 68
now I want that I only enter productCode in my textbook named txtProductCode, and press tab then ProductPrice(txtProductPrice) and ProductName(txtProductName) boxes fills automatically.
The code I tried to compare the Productcode and access values is:
private void txtProdcutCode_Leave(object sender, EventArgs e)
{
///////////////////////////////////////////////////////////////////////
InitializeComponent();
string sql;
int productCode = 0;
productCode = Convert.ToInt32(txtProdcutCode.Text);
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, dbo.ProductLog.ProductName";
sql = " WHERE ProductLog.ProductCode = " + txtProdcutCode.Text + "";
SqlConnection cn = new SqlConnection();
SqlCommand rs = new SqlCommand();
SqlDataReader sdr = null;
clsConnection clsCon = new clsConnection();
clsCon.fnc_ConnectToDB(ref cn);
rs.Connection = cn;
rs.CommandText = sql;
sdr = rs.ExecuteReader();
while (sdr.Read())
{
txtProductPrice.Text = sdr["ProductPrice"].ToString();
txtProductName.Text = sdr["ProductName"].ToString();
}
//lblTotalQuestion.Text = intQNo.ToString();
sdr.Close();
rs = null;
cn.Close();
/////////////////////////////////////////////////////////////////////////
}
but in line productCode = Convert.ToInt32(txtProdcutCode.Text); it says Input string was not in a correct format.
Please help me out with this problem.
EDIT:
I've also tried this code :
private void txtProdcutCode_Leave(object sender, EventArgs e)
{
///////////////////////////////////////////////////////////////////////
string sql;
// int productCode = 0;
//productCode = Convert.ToInt32(txtProdcutCode.Text);
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, AND dbo.ProductLog.ProductName";
sql = " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
SqlConnection cn = new SqlConnection();
SqlCommand rs = new SqlCommand();
SqlDataReader sdr = null;
clsConnection clsCon = new clsConnection();
clsCon.fnc_ConnectToDB(ref cn);
rs.Connection = cn;
rs.CommandText = sql;
sdr = rs.ExecuteReader();
while (sdr.Read())
{
txtProductPrice.Text = sdr["ProductPrice"].ToString();
txtProductName.Text = sdr["ProductName"].ToString();
}
//lblTotalQuestion.Text = intQNo.ToString();
sdr.Close();
rs = null;
cn.Close();
/////////////////////////////////////////////////////////////////////////
}
but it says Incorrect syntax near the keyword 'WHERE'. means I am making mistake in calling database table in my query, but I am not able to find out the mistake ...
There are some issues with your SQL.
You were originally overwriting the sql variable and only ended up with a WHERE clause;
You don't have a FROM statement so the database doesn't know where you're trying to retrieve records from.
The use of AND in a SELECT statement is incorrect; you just need commas to separate the fields.
You're never selecting ProductPrice from the DB, but selecting ProductName twice!
You're not using parameterized SQL for your query, leaving your app open to SQL injection attacks.
To address this (points 1-4, I will leave point 5 for your own research),
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, AND dbo.ProductLog.ProductName";
sql = " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
Should be
sql += "SELECT ProductName, ProductPrice";
sql += " FROM dbo.ProductLog";
sql += " WHERE ProductCode = '" + txtProdcutCode.Text + "'";
Note: This answer assumes that the value of txtProductCode.Text is an integer!
EDIT: It turns out that the column, ProductCode, was a VarChar. For OP
and others reading this question, when you get SQL conversion errors
check your column datatype in SQL server and make sure it matches what
you're submitting.
That's the basics. There are many other improvements that can be made but this will get you going. Brush up on basic SQL syntax, and once you get that down, look into making this query use a parameter instead of directly placing txtProductCode.Text into your query. Good luck!
Never call InitializeComponent method twice.It's creating your form and controls and it's calling in your form's constructor.Probably when you leave your textBox it's creating again and textBox will be blank.therefore you getting that error.Delete InitializeComponent from your code and try again.
Update: your command text is wrong.here you should use +=
sql += " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
But this is not elegant and safe.Instead use paramatirezed queries like this:
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandText = "SELECT dbo.ProductLog.ProductName,dbo.ProductLog.ProductName WHERE dbo.ProductLog.ProductCode = #pCode";
cmd.Parameters.AddWithValue("#pCode", txtProdcutCode.Text );

Categories