Combo box Where Clause - c#

i have a table of POMain po_no and a table of Shipping invoice, then when i search the po_no, i will add an invoice. the thing i want to do is if the po_no already have an invoice the po_no in search button will not appear
public AddForm()
{
InitializeComponent();
string ID = cb_po_search.SelectedValue.ToString();
string strPRSconn = ConfigurationManager.ConnectionStrings["POSdb"].ConnectionString;
SqlConnection sc = new SqlConnection(strPRSconn);
sc.Open();
string strQry = "SELECT POMain.po_no FROM POMain LEFT JOIN Shipping ON POMain.po_no = Shipping.po_no WHERE Shipping.invoice IS NULL AND POMain.po_no = '" + ID + "'";
SqlCommand scmd = new SqlCommand(strQry, sc);
SqlDataReader dr = scmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("po_no", typeof(string));
dt.Load(dr);
cb_po_search.ValueMember = "po_no";
cb_po_search.DisplayMember = "po_no";
cb_po_search.DataSource = dt;
sc.Close();
}
}

You need to use a LEFT OUTER join here instead of an INNER join
string strQry ="SELECT POMain.po_no FROM POMain INNER JOIN Shipping ON POMain.po_no = Shipping.po_no WHERE Shipping.invoice IS NULL";
And you need to add another condition to the WHERE clause at the end:
AND POMain.po_no = " + ID
Having said that, you would be much better off using a stored procedure instead of trying to form an inline query.

Related

System.Data.SqlClient.SqlException: Incorrect syntax near ')'

I am getting an error in my SQL command with which I am trying to retrieve values from a SQL Server database. It is showing a error in browser as mentioned in title. If I remove the brackets it shows error in AND operator
string jdate = (string)Session["jdate"];
string clas = (string)Session["class"];
string scode = (string)Session["scode"];
string dcode = (string)Session["dcode"];
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["dummyConnectionString"].ToString());
// error shows up on this line
string slct = "SELECT Route.Route_Source, Route.Route_Destination, Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time, Schedule.Route_rate_Ad , Seats." + jdate +
"Schedule.Sch_id FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id INNER JOIN Route ON Schedule.Route_id = Route.Route_id INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id WHERE (Route.Route_Source =" + scode + ") AND (Route.Route_Destination =" + dcode + ") AND (Seats.Class=" + clas + ") ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlDataAdapter da = new SqlDataAdapter(slct, cn);
DataSet ds = new DataSet();
da.Fill(ds);
SearchView.DataSource = ds;
SearchView.DataBind();
You should use a parameterized query.
This would allow a more understandable query text, avoid simple syntax errors
(like the missing comma at the end of the first line (jdate)),
avoid Sql Injections and parsing problems with strings containing quotes or decimal separators
string slct = #"SELECT Route.Route_Source, Route.Route_Destination,
Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time,
Schedule.Route_rate_Ad, Seats." + jdate + ", Schedule.Sch_id " +
#"FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id
INNER JOIN Route ON Schedule.Route_id = Route.Route_id
INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id
WHERE (Route.Route_Source = #scode)
AND (Route.Route_Destination =#dcode)
AND (Seats.Class=#class)
ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlCommand cmd = new SqlCommand(slct, cn);
cmd.Parameters.AddWithValue("#scode", scode);
cmd.Parameters.AddWithValue("#dcode", dcode);
cmd.Parameters.AddWithValue("#class", clas);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);

sort date into descending order

I want to display the date into descending order in Gridview as default.
DataTable dt = new DataTable();
SqlDataAdapter adp =
new SqlDataAdapter("SELECT Customer.CustomerID, Customer.lastname, Customer.firstname,
Ticket.Date, Ticket.Store, Ticket.Amount, Ticket.NoStub " +
"FROM Customer INNER JOIN Ticket ON Customer.CustomerID = Ticket.CustomerID
WHERE Customer.CustomerID like " + txtCustomerID.Text, cn);
adp.Fill(dt);
gvHistory.DataSource = dt;
Just add:
order by Ticket.Date desc
to the end of your sql statement, like the following:
DataTable dt = new DataTable();
SqlDataAdapter adp = new SqlDataAdapter("SELECT Customer.CustomerID, Customer.lastname, Customer.firstname, Ticket.Date, Ticket.Store, Ticket.Amount, Ticket.NoStub " +
"FROM Customer INNER JOIN Ticket ON Customer.CustomerID = Ticket.CustomerID WHERE Customer.CustomerID like " + txtCustomerID.Text + " order by Ticket.Date desc", cn);
adp.Fill(dt);
gvHistory.DataSource = dt;
As #Adels answer you can order by changing your sql statement, if you want to do it by code. try DataGridView.Sort method as below
gvHistory.Sort(gvHistory.Columns["ColumnName"], ListSortDirection.Descending);
I suggest using the Sort function on the data grid, as Damith recommended
DO NOT PUT USER PARAMETERS DIRECTLY INTO THE SQL STATEMENT. You must use WHERE Customer.CustomerID like #customerId and then add a parameter to the command, with name = #customerId and value = txtCustomerID.Text. This 1) prevents user input from destroying the database, 2) prevents bloating the SQL plan cache.
System.Data.DataTable dt = new System.Data.DataTable();
System.Data.SqlClient.SqlDataAdapter adp = new System.Data.SqlClient.SqlDataAdapter(
"SELECT Customer.CustomerID,
Customer.lastname,
Customer.firstname,
Ticket.Date,
Ticket.Store,
Ticket.Amount,
Ticket.NoStub " +
"FROM Customer INNER JOIN Ticket ON
Customer.CustomerID = Ticket.CustomerID WHERE
Customer.CustomerID like " + txtCustomerID.Text + "
order by Ticket.Date desc", cn);
adp.Fill(dt);
gvHistory.DataSource = dt;

i need to get more than one value from database sql

I need to get 6 values from database and bind them to link button texts her is the code
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//string post = Request.QueryString["post"];
////string title = "nokia";
string date = DateTime.Now.ToShortDateString();
SqlConnection conn = new SqlConnection();
conn.ConnectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\nokiaoaq\Desktop\WebSite1\App_Data\Database.mdf;Integrated Security=True;User Instance=True";
try
{
conn.Open();
//string str = "insert into Table1 (title , date_ ,www, cat) values (' " + TextBox1.Text + "','" + DateTime.Now.ToShortDateString() + "','" + TextBox2.Text + "','" + DropDownList1.SelectedItem.Text + "')";
////string str = "INSERT INTO Table1 (title,date_,www ) values ('ddddddd','aaaaaaa','qqqqqq')";
string str =
//"SELECT from table1 WHERE cat = 1 and datee='" + date + "'ORDER BY datee";
"SELECT table1.title FROM table1 WHERE cat = 1 and datee='" + date + "'ORDER BY datee DESC";
SqlCommand objcmd = new SqlCommand(str, conn);
SqlDataAdapter da1 = new SqlDataAdapter(objcmd);
DataTable dt = new DataTable();
da1.Fill(dt);
//DataRow dr = new DataRow();
//DataRow dr = ds.Tables[0].Rows[0];
foreach (DataRow dr in dt.Rows)
{
ml1.Text = dr[0].ToString();
ml2.Text = dr[1].ToString();
ml3.Text = dr[2].ToString();
ml4.Text = dr[3].ToString();
ml5.Text = dr[4].ToString();
ml6.Text = dr[5].ToString();
}
}
catch (Exception ex)
{
Label4.Text = "Failed to connect to data source";
}
finally
{
conn.Close();
}
}
}
ml is link button id
You are trying to assign 6 fields from the row returned to 6 different textboxes, but your select query asks for just one field. If you want more than one field returned then add their names to the select query (change fieldX to the appropriate field name).
string str = "SELECT title, field1, field2, field3, field4, field5 " +
"FROM table1 WHERE cat = 1 and datee=#dt ORDER BY datee DESC";
also do not use string concatenation to build the sql statement. Use always a parametrized query
SqlCommand objcmd = new SqlCommand(str, conn);
objcmd.Parameters.AddWithValue("#dt", datee);
.....
this will avoid problem with formatting strings, date, numbers etc, but also the sql injection problem.
By the way, I hope that your code returns just one row because, as it stands now, if you have more than one row returned then only the one with the earliest date will be shown in the textboxes. (And if this is the case then the order by is useless). If you have more than one row returned then you should consider to bind the datatable to a GridView to show all records returned.

compare two tables and update the third one

Suppose I have a table in SQL "abc" and with in it there is a column "number" and this column contains (1,2,3,4) etc.
In my second table "xyz" I have a column "number" and this column contains (1,2,3,4,5,6,7,8,9).
Now I want to compare these two and insert equal data within third table.
So how can I do this?
code :
string str = "SELECT Invoice_Details.PGI_ID, PARTY_BOOKING_DETAILS.PGI_ID AS abc ";
str += "FROM PARTY_BOOKING_MAIN INNER JOIN ";
str += " PARTY_BOOKING_DETAILS ON PARTY_BOOKING_MAIN.PBM_ID = PARTY_BOOKING_DETAILS.PBM_ID CROSS JOIN ";
str += " Invoice_Details where PARTY_BOOKING_MAIN.PM_ID = 1 ";
SqlConnection con = new SqlConnection("data source = .; database = ePartyDatabase01; integrated security = true");
con.Open();
SqlCommand cmd1 = new SqlCommand("update Invoice_Details set [status] = #a", con);
SqlCommand cmd = new SqlCommand(str, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr["PGI_ID"].ToString() == dr["abc"].ToString())
{
cmd1.Parameters.AddWithValue("#a", 1);
}
}
dr.Close();
cmd1.ExecuteNonQuery();
con.Close();
You probably want to use some kind of this query:
insert into table3 (number)
select
t1.number
from abc t1
inner join xyz t2
on t1.number = t2.number
I haven't tested this yet, but you might not even need C#, try something like this:
SELECT xyz.number
INTO third_table
FROM (
SELECT t1.number
FROM first_table t1 JOIN second_table t2 ON t1.number = t2.number
) AS xyz
Maybe something like this:
INSERT INTO table3(number)
SELECT
number
FROM
xyz
WHERE NOT EXISTS
(
SELECT
NULL
FROM
abc
WHERE
abc.number=xyz.number
)

Dataset returning ZERO results

I am trying to fill in a combobox on my winform app from the database. I know there is info in the DB. I know the SP works. It returns the correct ColumnNames. But the DataSet itself is empty? Help!?!?
Call from my form-->
cboDiagnosisDescription.Properties.DataSource = myDiagnosis.RetrieveDiagnosisCodes();
The RetrieveDiagnosisCodes -->
public DataSet RetrieveDiagnosisCodes()
{
string tableName = "tblDiagnosisCues";
string strSQL = null;
DataSet ds = new DataSet(tableName);
SqlConnection cnn = new SqlConnection(Settings.Default.CMOSQLConn);
//strSQL = "select * from " & tableName & " where effectivedate <= getdate() and (termdate >= getdate() or termdate is null)"
strSQL = "select tblDiagnosisCues.*, tblDiagnosisCategory.Description as CategoryDesc, tblDiagnosisSubCategory.Description as SubCategoryDesc " + "FROM dbo.tblDiagnosisCategory INNER JOIN " + "dbo.tblDiagnosisSubCategory ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category INNER JOIN " + "dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID " + "where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description";
SqlCommand cmd = new SqlCommand(strSQL, cnn) {CommandType = CommandType.Text};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
//cnn.Open();
da.Fill(ds);
}
catch (Exception ex)
{
throw;
}
finally
{
cmd.Dispose();
da.Dispose();
//ds.Dispose();
cnn.Close();
cnn.Dispose();
}
return ds;
}
The reason I know it is returning the correct column names is that I tried the following with a DevExpress LookUpEdit box and it populates the correct columns from the DB -->
var myDiagnosis = new Diagnosis();
var ds = myDiagnosis.RetrieveDiagnosisCodes();
lkuDiagnosis.Properties.DataSource = ds;
lkuDiagnosis.Properties.PopulateColumns();
lkuDiagnosis.Properties.DisplayMember = ds.Tables[0].Columns[1].ColumnName;
lkuDiagnosis.Properties.ValueMember = ds.Tables[0].Columns[0].ColumnName;
Ideas? Mainly, I don't even know how to proceed tracking this down...How to debug it?
EDIT 1
Based on a comment I ran the following SQL by itself and it returned 650 results...
select tblDiagnosisCues.*,
tblDiagnosisCategory.Description as CategoryDesc,
tblDiagnosisSubCategory.Description as SubCategoryDesc
FROM dbo.tblDiagnosisCategory
INNER JOIN dbo.tblDiagnosisSubCategory
ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category
INNER JOIN dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID
where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description
//cnn.open();
...
//ds.dispose();
There is no need to specify a table name in the dataset constructor. The fill method will add a table. Also no need to open the connection since the sqldataadapter will open and close the connection for you. Also, I prefer to return a datatable as opposed to dataset with one table.
The code could be refactored to the following...of coure add the try catch if you want to log the exception.
public DataTable RetrieveDiagnosisCodes()
{
//string tableName = "tblDiagnosisCues";
DataSet ds = new DataSet();
Datatable dt = null;
//strSQL = "select * from " & tableName & " where effectivedate <= getdate() and (termdate >= getdate() or termdate is null)"
string strSQL = "select tblDiagnosisCues.*, tblDiagnosisCategory.Description as CategoryDesc, tblDiagnosisSubCategory.Description as SubCategoryDesc " + "FROM dbo.tblDiagnosisCategory INNER JOIN " + "dbo.tblDiagnosisSubCategory ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category INNER JOIN " + "dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID " + "where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description";
using(SqlDataAdapter da = new SqlDataAdapter(strSQL, Settings.Default.CMOSQLConn))
{
da.Fill(ds);
}
if (ds.Tables.Count > 0)
{
dt = ds.Tables[0];
}
return dt;
}
If the data is properly binding to another control, it indicates that there is an issue with the databinding process. What does your databinding setup look like for the combobox in question? Are all the column names properly spelled and setup?

Categories