adding a data source to the gridview dynamically in C# - c#

Here i have tried to do bind the gridview as per the selection in the checkboxlist.
I'm getting only blank page when its executed. can any one specify what's the mistake?
protected void Button1_Click(object sender, EventArgs e)
{
String query = "Select Proj_id,Proj_name,Front_end,Back_end from Proj_details where Front_end = 'Android'";
String[] frontend ={ "Android", "Asp", "Asp.net", "C#.net", "J2EE", "Java", "Matlab", "NS2", "PHP", "VB", "VB.net" };
try
{
for (int i = 0; i <= CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Selected)
query = query.Insert(query.Length, frontend[i] + "','");
}
con.Open();
query = query.Remove(query.Length - 1);
query = query.Remove(query.Length - 1);
query = query.Insert(query.Length, ")");
SqlDataAdapter sqlada = new SqlDataAdapter(query, con);
DataSet ds = new DataSet();
sqlada.Fill(ds, "Proj_details");
gv_search_project.DataSource = ds.Tables[0];
gv_search_project.DataBind();
}
catch (Exception ex)
{
}
finally
{
Label1.Text = query.ToString();
}
}

You're going out of the array here:
for (int i = 0; i <= CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Selected)
query = query.Insert(query.Length, frontend[i] + "','");
}
You need to replace:
i <= CheckBoxList1.Items.Count
With:
i < CheckBoxList1.Items.Count

gv_search_project.DataSource = ds.Tables["Proj_details"];

You are building a query by appending additional Front_end values, but the base query you are appending to has a where clause like this:
where Front_end = 'Android'
So (if I read your code correctly) the resulting query is (for instance):
Select Proj_id,Proj_name,Front_end,Back_end
from Proj_details
where Front_end = 'Android'Android','C#.net','Matlab','VB')
To start with the query i simply broken. And secondly I think what you intended was to have an IN clause:
String query = "Select Proj_id,Proj_name,Front_end,Back_end from Proj_details where Front_end in ('Android','";
This, coupled with Amiram Korach's note about < vs <= should make the code work. But it will always include 'Android' (which you initial attempt also did).
Do change you empty catch clause though:
catch (Exception ex)
{
}
If you hadn't been swallowing all exceptions you would probably have found the problems yourself.

Related

What is the easiest way to update a batch of records using only one trip?

Normally you will do one update at a time inside a loop. If you have 100 records, you will have 100 trips to the server which is not desirable. How can I update a group of records with a single round trip to the database.
using System.Data.SqlClient;
for (int ii = 0; ii < ptList.Length; ii++) {
sql = #"update [CCVT].[dbo].[_tb_NCVT_Points] set PointDateTime = CONVERT(datetime, '"
+ ptList[ii]._dateDt.ToString("yyyy-MM-dd HH:mm:ss.FFF") + "', 121), PointStatus = '"
+ ptList[ii]._statStr + "', PointValue =" + ptList[ii]._valDoub.ToString()
+ " WHERE Pointkey = '" + ptList[ii]._pointName + "'; ";
theActiveConnection.Open();
SqlCommand cmd = new SqlCommand(sql, theActiveConnection);
try {
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (Exception eX) {
//handle exceptions
}
}
Please do not down vote this question.
The question How can I update multiple rows in a table with SQL query?
did not ask for one trip, and their answer did not yield one trip!! Did you see the ExecuteNonQuery action is inside the loop?? That is not my question and that is not my answer!
foreach (DataGridViewRow row in dataGridView2.Rows)
{
cm.Parameters["#Qty"].Value = row.Cells[2].Value;
cm.Parameters["#Description"].Value = row.Cells[3].Value;
cm.Parameters["#Price"].Value = row.Cells[4].Value;
cm.ExecuteNonQuery();
}
cn.Close();
SqlCommand cmd = new SqlCommand("", theActiveConnection);
StringBuilder sql = new StringBuilder();
for (int ii = 0; ii < ptList.Length; ii++) {
sql.AppendLine("UPDATE [CCVT].[dbo].[_tb_NCVT_Points]");
sql.AppendLine($"SET PointDateTime = CONVERT(datetime, #PointDateTime{ii}, 121), PointStatus = #PointStatus{ii}, PointValue = #PointValue{ii}");
sql.AppendLine($"WHERE Pointkey = '#PointKey{ii};");
cmd.Parameters.AddWithValue($"#PointDateTime{ii}",ptList[ii]._dateDt.ToString("yyyy-MM-dd HH:mm:ss.FFF"));
cmd.Parameters.AddWithValue($"#PointStatus{ii}",ptList[ii]._statStr);
cmd.Parameters.AddWithValue($"#PointValue{ii}",ptList[ii]._valDoub.ToString());
cmd.Parameters.AddWithValue($"#Pointkey{ii}",ptList[ii]._pointName);
}
try {
cmd.CommandText = sql.ToString();
theActiveConnection.Open();
cmd.ExecuteNonQuery();
}
catch (Exception eX) {
//handle exceptions
}
finally {
cmd.Dispose();
theActiveConnection.Close();
}
There are many ways to handle this issue, depending on how close and how different the commands are. In your case I think this is best.
The best performing way is to use table valued parameters with a stored procedure
https://msdn.microsoft.com/en-us/library/bb675163(v=vs.110).aspx
The simple way is to just concat SQL Statements with semicolon using a StringBuilder or .... But be aware that this has limitations in length!!!
Why not use Dapper - a simple object mapper for .Net
var list = ptList.select(p => new{
DateTime = p._dateDt,
Status = p._statStr,
Value = p._valDoub,
Key = p._pointName
});
using(var connection = new SqlConnection...)
{
connection.open()
connection.Execute("update [CCVT].[dbo].[_tb_NCVT_Points] set PointDateTime = #DateTime, PointStatus = #Status, PointValue = #Value
WHERE Pointkey = #Key", list);
}
The straight answer was posted by Andrew, but it depends on where your data comes from.
If the list of points is already in the database, and you are querying it into a list (one SELECT with a loop to fill up the list), then calling the large number of updates, you should do directly an UPDATE FROM which combines the SELECT and UPDATE in a single statement. One single trip to the server, with no unneccessary rows over the network.

Date-picker using select statement oracle

I'm trying to implement date-picker functionality in my project, but I can't do it quite right. I'm trying to pass the date-picker value in my oracle string so that it will compare with my db column and return results on the date criteria...
Whenever I pass it to the select statement it won't generate errors particularly but on button click it doesn't perform anything except it shows "not connected".
str = "Select * from sania.doctor where APPOINTMENT_DATE = "+ datepicker1.value;
It is clear it is logical mistake but I'm new to this C# concepts I need someone to tell me how to pass it and then display the results as well.
private void button1_Click(object sender, EventArgs e)
try
{
OracleCommand com;
OracleDataAdapter oda;
string ConString = "Data Source=XE;User Id=system;Password=sania;";
OracleConnection con = new OracleConnection(ConString);
{
// string id = dateTimePicker1.Text.Trim();
con.Open();
// str = "Select * from sania.doctor where APPOINTMENT_DATE = " + dateTimePicker1.value;
str = "select * from sania.doctor where APPOINTMENT_DATE to_date('"+dateTimePicker1.Value.ToString("yyyyMMdd") + "', 'yyyymmdd')";
com = new OracleCommand(str);
oda = new OracleDataAdapter(com.CommandText, con);
dt = new DataTable();
oda.Fill(dt);
Rowcount = dt.Rows.Count;
//int val = 0;
for (int i = 0; i < Rowcount; i++)
{
dt.Rows[i]["APPOINTMENT_DATE"].ToString();
//if (id == dateTimePicker1.Value)// this LINE SHOWS ERROR--because it is a string and I am using date with it. Don't know conversion
// {
// val = 1;
//}
}
// if (val == 0)
// { MessageBox.Show("INVALID ID"); }
// else
// {
DataSet ds = new DataSet();
oda.Fill(ds);
if (ds.Tables.Count > 0)
{
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
else { MessageBox.Show("NO RECORDS FOUND"); }
}
}
//}
catch (Exception)
{ MessageBox.Show("not connected"); }
}
Do not put values into SQL directly, use bind variables/parametes instead. For Oracle:
// :prm_Appointment_Date bind variable declared within the query
String str =
#"select *
from sania.doctor
where Appointment_Date = :prm_Appointment_Date";
....
using(OracleCommand q = new OracleCommand(MyConnection)) {
q.CommandText = str;
// datepicker1.Value passed into :prm_Appointment_Date via parameter
q.Parameters.Add(":prm_Appointment_Date", datepicker1.Value);
...
}
Doing like that you can be safe from either SQL Injection or Format/Culture differences

How to execute a ExecuteNonQuery with List parameters in Where Clause

My code looks like this:
var settings = ConfigurationManager.ConnectionStrings["InsurableRiskDB"];
string server = ConfigurationManager.AppSettings["Server"];
string cs = String.Format(ConfigurationManager.AppSettings[settings.ProviderName], ConfigurationManager.AppSettings[server]);
SqlConnection connection = new SqlConnection(cs);
string PolicyKeys = "";
for (int i = 0; i < keys.Count(); i++)
{
if (i == keys.Count() - 1)
PolicyKeys += keys[i] ;
else
PolicyKeys += keys[i] + ", ";
}
//have to change the code to pull the user's NBK.
string user = "'DATALOAD'";
const string updateQuery = #"UPDATE [InsurableRisk].[dbo].[Policy]
SET [InsuranceCarrierKey] = #ToKey
,[AuditUser] = #User
,[AuditDate] = SYSDATETIME()
WHERE PolicyKey in (#PolicyKeys) and InsuranceCarrierKey = #FromKey";
using (connection)
{
using (SqlCommand dataCommand = new SqlCommand(updateQuery, connection))
{
dataCommand.Parameters.AddWithValue("#ToKey", toKey);
dataCommand.Parameters.AddWithValue("#User", user);
dataCommand.Parameters.AddWithValue("#PolicyKeys", PolicyKeys);
dataCommand.Parameters.AddWithValue("#FromKey", fromKey);
connection.Open();
dataCommand.ExecuteNonQuery();
connection.Close();
}
}
res = true;
}
catch (Exception ex)
{
MessageBox.Show("There is an error while try in save the changes " + ex.Message, "Error Message", MessageBoxButtons.OKCancel);
res = false;
}
return res;
Now, when i run this code, it says query is unable to execute. It throws and exception stating, it is unable to convert NVarchar to int for variable #PolicyKeys
Any suggestions as to what i am missing in this code?
Typically, in SQL you'd write an IN statement like this:
WHERE SomeColumn IN ('A', 'B', 'C')
What you're doing is the equivalent of this in SQL (which won't work):
WHERE SomeColumn IN ('A, B, C')
Change your SQL statement accordingly: (modified from this answer)
WHERE PolicyKey in ({0})
And then add your parameters in a loop, like this:
var parameters = new string[keys.Count()];
for (int i = 0; i < keys.Count(); i++)
{
parameters[i] = string.Format("#Key{0}", i);
cmd.Parameters.AddWithValue(parameters[i], keys[i]);
}
cmd.CommandText = string.Format(updateQuery, string.Join(", ", parameters));

Taking values into an array of textboxes (ASP.NET using C#)

So I have an array of textboxes dynamically appear (The number of textboxes depends upon how a number from a database). They draw to the screen just fine.
i = 0;
while (i < size)
{
pnlTxtBoxes.Controls.Add(labels[i]);
pnlTxtBoxes.Controls.Add(txtBoxes[i]);
pnlTxtBoxes.Wrap = true;
i++;
}
Like I said, the textboxes appear and the labels are displaying correctly. But when I go to retrieve the text from them, I get the error "Object reference not set to an instance of an object."
i = 0;
while (i < size)
{
values[i] = txtBoxes[i].Text;
txtBoxes[i].Visible = false;
labels[i].Visible = false;
i++;
}
Does anybody have an idea as to why I'm getting this error (and what I can do to fix it)?
EDIT: Here is all of the code. This is just a development DB, so I am not worried about showing the password
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MySql.Data.MySqlClient;
public partial class dieClearanceCalc : System.Web.UI.Page
{
static string connectionString = "database=localhost;database=matedevdb;uid=dev;pwd=123;";
MySqlConnection con = new MySqlConnection(connectionString);
MySqlCommand cmd = new MySqlCommand("SELECT shapeName FROM tblShapes;");
MySqlDataReader reader;
int size;
TextBox[] txtBoxes;
Label[] labels;
protected void Page_Load(object sender, EventArgs e)
{
cmd.Connection = con;
try
{
con.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
shapeSelection.Items.Add(reader.GetString(0));
}
reader.Close();
}
catch (Exception ex)
{
Response.Write("<p style='Color:red'>Error:<br/>" + ex + "</p>");
}
}
protected void shapeSelected(object sender, EventArgs e)
{
string[] labelTxt;
int i = 0;
//Make current elements invisable
lblShape.Visible = false;
shapeSelection.Visible = false;
btnSelectShape.Visible = false;
// find the size of the arrays
cmd.CommandText = "SELECT COUNT(varID) FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
reader = cmd.ExecuteReader();
if (reader.Read())
{
size = reader.GetInt32(0);
}
reader.Close();
labelTxt = new string[size];
labels = new Label[size];
txtBoxes = new TextBox[size];
// gather the labels from the db
cmd.CommandText = "SELECT varDesc FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
reader = cmd.ExecuteReader();
i = 0;
while (reader.Read())
{
labelTxt[i] = reader.GetString("varDesc");
i++;
}
reader.Close();
i = 0;
while (i < size)
{
labels[i] = new Label();
txtBoxes[i] = new TextBox();
labels[i].Text = labelTxt[i];
i++;
}
i = 0;
while (i < size)
{
pnlTxtBoxes.Controls.Add(labels[i]);
pnlTxtBoxes.Controls.Add(txtBoxes[i]);
pnlTxtBoxes.Wrap = true;
i++;
}
btnSendData.Visible = true;
//Response.Write(size); test to see if the size variable is working
Response.Write(size);
}
protected void calc(object sender, EventArgs e)
{
//declarations
formula diagonal, periphery;
string dFormula = "", pFormula = "";
string[] variables;
string[] values;
int i = 0;
//end of declarations
// This value must be retrievd again, because somewhere size is getting a value of 0
cmd.CommandText = "SELECT COUNT(varID) FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
reader = cmd.ExecuteReader();
if (reader.Read())
{
size = reader.GetInt32(0);
}
reader.Close();
variables = new string[size];
values = new string[size];
i = 0;
while (i < size)
{
values[i] = txtBoxes[i].Text;
txtBoxes[i].Visible = false;
labels[i].Visible = false;
i++;
}
btnSendData.Visible = false;
// retrieve the diagonal formula from the db
cmd.CommandText = "SELECT diagonalFormula, peripheryFormula FROM tblShapes WHERE shapeName='" + shapeSelection.SelectedValue + "'";
reader = cmd.ExecuteReader();
while (reader.Read())
{
dFormula = reader.GetString("diagonalFormula");
pFormula = reader.GetString("peripheryFormula");
}
reader.Close();
Response.Write(size);
// gather the variable names from the db
cmd.CommandText = "SELECT varName FROM tblVariables WHERE shapeID IN(SELECT shapeID FROM tblShapes WHERE shapeName= '" + shapeSelection.SelectedValue + "')";
reader = cmd.ExecuteReader();
while (reader.Read())
{
variables[i] = reader.GetString("varName");
i++;
}
reader.Close();
con.Close();
diagonal = new formula(dFormula, variables, values);
periphery = new formula(pFormula, variables, values);
txtDiagonal.Visible = true;
txtPeriphery.Visible = true;
txtDiagonal.Text = diagonal.getEquation();
txtPeriphery.Text = periphery.getEquation();
}
public static double Evaluate(string expression)
{
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.Add("expression", string.Empty.GetType(), expression);
System.Data.DataRow row = table.NewRow();
table.Rows.Add(row);
return double.Parse((string)row["expression"]);
}
}
I reckon you initialize the labels and txtBoxes in if IsPostBack block and don't save it in ViewState or Session.
Edit:
saw your code labels and txtBoxes was initialized in shapeSelected method. same problem will happen: they are lost between postback.
So they are empty in event handler when postback because whole Page object was re-created when postback. Asp.net runtime helps to load content from ViewState for control.But for class member variable you have to maintain by yourself.like:
public string NavigateUrl
{
get
{
string text = (string) ViewState["NavigateUrl"];
if (text != null)
return text;
else
return string.Empty;
}
set
{
ViewState["NavigateUrl"] = value;
}
}
Above code comes from:
Understanding ASP.NET View State
http://msdn.microsoft.com/en-us/library/ms972976.aspx
The article also introduces View State and Dynamically Added Controls
An important thing to remember when programming with ASP.NET is that your whole object model on a page gets created with every web request again and again. This means that if you add some controls to you page dynamically in an event that does not happen each page load they are not going to survive the postback if you don't add them again somehow.
You can read about Asp.Net page Life Cycle here: http://msdn.microsoft.com/en-us/library/ms178472.aspx
I don't think there is a standard way to solve your problem, but what you are trying to do can be achieved in several ways. One was already mentioned to you - usage of ViewState. Another one would be hitting database on each post back, and making sure you are recreating the controls each time the page is served. One more way is to somehow encode the data that is required for recreating your controls and make sure that they are passed with each post back. The latter is essentially what ViewState does, but you can do it more efficiently if you want to reduce the size of you ViewState, and thus size in bytes of your postback and page.
Without seeing more code, I can only guess that the problem lies with where you populate the txtBoxes[] array. Make sure there are no null values in that array.

How to write: insert into table ALL except X, if statement

Second question of all time on this community! I am a noob and my weakness are if statements within or amoungst loops and other if statements.
So here is my scenario. This method inserts anything into a database, but I want to validate something. Instead of adding anything into the database, I do not want anything entered in that begins with "LIFT", I want the method to skip over that line and proceed to the next one. Is there a way I can program this into this method? Or do I need to write a new method? Thanks a bunch!
public bool BatchInsert(string table, string[] values)
{
string statement = "INSERT INTO " + table + " VALUES(";
for (var i = 0; i < values.Length - 1; i++)
{
if(values[i].Contains("'")){
values[i] = values[i].Replace("'", "''");
}
statement += "'"+values[i]+"', ";
}
statement += "'" + values[values.Length - 1] + "');";
SqlCommand comm = new SqlCommand(statement, connectionPCICUSTOM);
try
{
comm.Connection.Open();
comm.ExecuteNonQuery();
}
catch (Exception e)
{
KaplanFTP.errorMsg = "Database error: " + e.Message;
}
finally
{
comm.Connection.Close();
}
return true;
}
A couple hints. Don't += string types as it slows down performance. I also prefer foreach loops as the code is cleaner and easier to read/less likely to mess up the index. Also make using of the using statement to ensure proper disposal.
Assuming you have a reference to System.Linq you can use the following. I didn't test it but it should work:
public bool BatchInsert(string table, IEnumerable<string> values)
{
var sql = new StringBuilder();
sql.Append("INSERT INTO " + table + " VALUES(");
var newValues = values.Where(x => !x.StartsWith("LIFT")).Select(x => string.Format("'{0}'", x.Replace("'", "''")));
sql.Append(string.Join("","", newValues.ToArray()));
sql.Append(")");
using (var comm = new SqlCommand(statement, connectionPCICUSTOM))
{
try
{
comm.Connection.Open();
comm.ExecuteNonQuery();
}
catch (Exception e)
{
KaplanFTP.errorMsg = "Database error: " + e.Message;
}
finally
{
comm.Connection.Close();
}
}
return true;
}
If your goal is to iterate through your collection of 'values', leaving values beginning with 'lift' and their corresponding columns untouched, you may have to revise the way your INSERT Query is constructed. You will add columns as needed, instead of assuming that each value will be accounted for. Basically, you will need to use the form:
INSERT INTO tablename (col1, col2...) VALUES (val1, val2...)
For example:
string statement = "INSERT INTO tablename ";
string columns = "(";
string values = "(";
for (var i = 0; i < values.Length - 1; i++)
{
//if values doesn't contain lift, add it to the statement
if(!values[i].contains("LIFT")){
//columnName is a collection of your db column names
columns += "'"+columnName[i]+"'";
values += "'"+values[i]+"'";
}
}
columns += ")";
values += ")";
statement += columns +" VALUES " + values;
Like some of the comments have stated, this approach opens you up to SQL injections. Use with caution.
EDIT : Sorry, I missed where you said 'starts with 'LIFT'. Revise the .contains() line to the following:
if(!values[i].StartsWith("LIFT")){

Categories

Resources