Microsoft SQL search table for entry - asp.net

I'm working on a inventory system for a micro brewery and I have a question about adding customers to a database. I want to add customers only if they don't already have an entry. What command could I use to check for that?
Here's my code so far (ASP.NET)
con.ConnectionString = "****"
con.Open()
cmd.Connection = con
cmd.CommandText = "INSERT INTO Customer(Name, Address) VALUES('" & Namea & "','" & Addressa & "')"
cmd.ExecuteNonQuery()
cmd.CommandText = "SELECT Customer_ID FROM Customer WHERE (Name = '" & Namea & "')"
custID = cmd.ExecuteScalar
cmd.CommandText = "SELECT Order_Details_ID FROM OrderDetails WHERE Finished_Inventory_ID=" & OrdersInt & ""
ordrID = cmd.ExecuteScalar
cmd.CommandText = "INSERT INTO Orders(Customer_ID, Order_Details) VALUES(" & Integer.Parse(custID) & "," & Integer.Parse(ordrID) & ")"
cmd.ExecuteNonQuery()
con.Close()
Is there a Boolean command that will return true if there's already a entry with the specific Namea. I don't want multiple entries with the same customer name.

There are a number of ways to prevent duplicate entries. You can check first:
select count(*) records
from etc
Then look at the value of records. If it's 0, do the insert. Or you can use a subquery.
insert into table
(field1, field2, etc)
select value1, value2, etc
where (select count(*) etc ) = 0
or like this:
insert into table
(field1, field2, etc)
select value1, value2, etc
where not exists (select 1 from table etc)
In all cases, the etc part is a search for records you don't want to duplicate.

Related

Database query result to display in Label VB.net

I have a label in which I want to display my database query result. But the label displaying only first row not all the records. Can anyone here could help me with this? Tried searching but I found other answers confusing. Please help me.
Here is what I have so far.
FrontEnd
<asp:Label ID="Resulttext" runat="server" Text=""></asp:Label>
Backend
Protected Sub getUser()
Dim dt As New DataTable()
Dim conn As SqlConnection = New SqlConnection("myconnectionhere")
conn.Open()
Dim cmd As SqlCommand = New SqlCommand("mysqlhere", conn)
Dim da As SqlDataAdapter = New SqlDataAdapter(cmd)
da.SelectCommand = cmd
da.Fill(dt)
If dt.Rows.Count > 0 Then
Resulttext.Text = dt.Rows(0)("Fullname").ToString
End If
conn.Close()
End Sub
What I'm doing wrong? Thank you.
Already solve the problem and here is the answer.
If dt.Rows.Count > 0 Then
For i As Integer = 0 To dt.Rows.Count - 1
Resulttext.Text = dt.Rows(i)("Fullname").ToString & " " & Resulttext.Text
Next
End If
Resulttext.Text = dt.Rows(0)("Fullname").ToString
You are writing above code for display record in the Lable.
Meaning of above code is dt.Rows(RowIndex)(ColumnIndex/"Column valuse")
You passed 0 in the RowIndex Means it gives you First row and passed "FullName" in column value , So it gives fullname value of First row.
That's why it displays only one record.
For display all the value of FullName you have to change your query as below.
select distinct t1.id,
STUFF(
(SELECT ', ' + FullName
FROM yourtable t2
where t1.id = t2.id
FOR XML PATH (''))
, 1, 1, '') AS fullname
from yourtable t1;
Thus it gives fullName as comma separated and then you can write code
Resulttext.Text = dt.Rows(0)("Fullname").ToString
And it gives CSV for fullname and displays in the label

Search command using session variable asp.net

I have a name stored in a session variable called "name".
I have written the statement:
da = new SqlDataAdapter("Select empID from emp where empFirstName=' "+
Session["name"].ToString() + " '", connstring);
da.Fill(ds);
I have verified that the session variable is not empty. Yet i am not able to fetch the empID of the record that exists in the table. Is this statement correct?
You have spaces at the beginning and end of the string variable in SQL statement.
Try this, it should work:
da = new SqlDataAdapter("Select empID from emp where empFirstName='"+
Session["name"].ToString() + "'", connstring);
The problem was with the spaces over here:
' " + Session["name"].ToString() + " '"
^ ^
| |
that is why the values are suffixed and prefixed by a blank space.
You should try:
da = new SqlDataAdapter (
"Select empID from emp where empFirstName='" + Session["name"].ToString() + "'",
connstring);
da.Fill(ds);

error in submit button

I have an error in the execution of my code. It says "Syntax error in INSERT INTO statement". This is my code:
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click GridView1.Visible = True
Dim myConn As OleDbConnection
Dim sqlString, takenby, dest, client, car As String
Dim recordno As Integer
Dim dte, exptime As String
recordno = TextBox4.Text
dte = TextBox1.Text
car = ComboBox1.SelectedValue.ToString()
takenby = ComboBox2.SelectedValue.ToString
dest = ComboBox3.SelectedValue.ToString
client = TextBox2.Text
exptime = TextBox3.Text
myConn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\student\WebSite3\App_Data\Database.mdb;Persist Security Info=False;")
myConn.Open()
sqlString = "INSERT INTO DETAILED GISTEC CARS(Record No, Date, Car, Taken By, Destination, Client, Expected Time to Return)VALUES(?recordno, ?dte, ?car, ?takenby, ?dest, ?client, ?exptime);"
Dim cmd = New OleDbCommand(sqlString, myConn)
cmd.ExecuteNonQuery()
myConn.Close()
End Sub
You should change your query to use question mark placeholders and then add paramters to prevent (amongst other things) sql injection issues.
You also need to add square brackets to your column names if they have spaces in them:
sqlString = "INSERT INTO [DETAILED GISTEC CARS] ([Record No], [Date], [Car], [Taken By], [Destination], [Client], [Expected Time to Return]) VALUES (?, ?, ?, ?, ?, ?, ?);"
Dim cmd = New OleDbCommand(sqlString, myConn)
cmd.Parameters.Add(New OleDbParameter("Record No", recordno))
cmd.Parameters.Add(New OleDbParameter("Date", dte))
'etc
'etc
cmd.ExecuteNonQuery()
See this page about OleDbParameters for more information.
Try to execute query directly in Access until it works.
From here it looks like
You have no spaces around VALUES
Your table name contain spaces so better use [] to surround table name
Same with some column names.
Not sure of ?recordno syntax in vb so better use + operator
sqlString = "INSERT INTO [DETAILED GISTEC CARS]([Record No], [Date], [Car], [Taken By], [Destination], [Client], [Expected Time to Return]) VALUES (" + recordno + ", " + dte + ", " + car +", " + takenby, " + dest + ", " + client + ", " + exptime + ");"
An alternative to cad's concatenation method would be to use curly brace array placeholders. Something like this should do it:
sqlString = String.Format("INSERT INTO [DETAILED GISTEC CARS] ([Record No], [Date], [Car], [Taken By], [Destination], [Client], [Expected Time to Return]) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6});", recordno, dte, car, takenby, dest, client, exptime)
You should also put single quotes around non-numeric values, escape any user entered single quotes, and call the Access CDATE function for Date/Time columns. So, assuming dte is user entered data and exptime is a Date\Time column, those two variables might be set like this:
dte = "'" + TextBox1.Text.Replace("'", "''") + "'"
exptime = "CDATE('" + TextBox3.Text + "')"
and so on and so forth...

nested select statements taking too long to load on SQL server

I have a page that displays reports on a grid. The grid uses an Object data source which is bound to a class that returns data. The class itself uses standard SQL query to return a count of records and binds to a dataview. The issue we are having is that it takes about 10 minutes sometimes to load and I know there has to be a better way but cannot for the life of me, figure out what. Hoping to get some insights from anyone on how to optimize this for performance. The data class is shown below: any feedback would be appreciated. There are about 650 attorneys returned by the attorney view which is bound to 2 tables: attorneys and locations table. The view on which the counts are performed on is bound to 2 tables also: current cases and previous cases tables and that returns about 125,000 cases total. Caching is out of the question because the end user will be able to supply any start and end dates to generate the report.
Dim PendingStringBuilder As String = "((dbo.cases.attorney_id = dbo.attorneys.att_id) AND (dbo.cases.date_assigned <= #StartDate) AND (dbo.cases.closing_date >= #StartDate OR dbo.cases.closing_date IS NULL)) OR ((dbo.casepreviousattorneys.attorney_id =
dbo.attorneys.att_id) AND (dbo.casepreviousattorneys.previous_assignment_date <= #StartDate) AND (dbo.casepreviousattorneys.unassignment_date >= #StartDate OR dbo.casepreviousattorneys.unassignment_date IS NULL))"
Dim AssignedStringBuilder As String = "((dbo.cases.attorney_id = dbo.attorneys.att_id) AND (dbo.cases.date_assigned >= #StartDate) AND (dbo.cases.date_assigned <= #EndDate)) OR ((dbo.casepreviousattorneys.attorney_id = dbo.attorneys.att_id) AND (dbo.casepreviousattorneys.previous_assignment_date
>= #StartDate) AND (dbo.casepreviousattorneys.previous_assignment_date <= #EndDate))"
Dim CountTable As String = " dbo.cases WITH (NOLOCK) INNER JOIN dbo.tlkpcasetype ON dbo.cases.case_type_id = dbo.tlkpcasetype.case_type_id FULL OUTER JOIN dbo.casepreviousattorneys ON dbo.cases.case_no = dbo.casepreviousattorneys.case_no"
Dim dt As New DataTable("ReportTable")
Dim dr As DataRow
dt.Columns.Add("CasesPending", Type.[GetType]("System.Int32"))
dt.Columns.Add("CasesAssigned", Type.[GetType]("System.Int32"))
dt.Columns.Add("ProbationViolation", Type.[GetType]("System.Int32"))
dt.Columns.Add("BailOnly", Type.[GetType]("System.Int32"))
dt.Columns.Add("TotalCases", Type.[GetType]("System.Int32"))
dt.Columns.Add("AttorneyID", Type.[GetType]("System.Int32"))
dt.Columns.Add("AttorneyName", Type.[GetType]("System.String"))
dt.Columns.Add("AttorneyFirstName", Type.[GetType]("System.String"))
dt.Columns.Add("AttorneyLastName", Type.[GetType]("System.String"))
dt.Columns.Add("UnitID", Type.[GetType]("System.Int32"))
dt.Columns.Add("UnitName", Type.[GetType]("System.String"))
dt.Columns.Add("UnitType", Type.[GetType]("System.String"))
dt.Columns.Add("OfficeID", Type.[GetType]("System.Int32"))
dt.Columns.Add("Office", Type.[GetType]("System.String"))
If cn.State = ConnectionState.Closed Then cn.Open()
Dim cmd As SqlCommand
Dim rdr As SqlDataReader
strSQL = "SELECT DISTINCT dbo.attorneys.user_id, dbo.attorneys.att_id AS AttorneyID, dbo.attorneys.first_name +' '+ dbo.attorneys.last_name AS AttorneyName, dbo.attorneys.unit_id AS UnitID, dbo.tlkpunit.unit AS UnitName, dbo.tlkpunit.unit_type AS UnitType,
dbo.tlkpunit.office_id AS OfficeID, dbo.tlkpoffice.office AS Office, "
strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprCasesPending FROM " & CountTable & " WHERE (" & PendingStringBuilder & ")) As CasesPending, "
strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprCasesAssigned FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type <> 'Probation Violation') AND (dbo.tlkpcasetype.case_type <> 'Bail Only') AND (" & AssignedStringBuilder & ")) As CasesAssigned,
"
strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprProbationViolation FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type = 'Probation Violation') AND (" & AssignedStringBuilder & ")) As ProbationViolation, "
strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprBailOnly FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type = 'Bail Only') AND (" & AssignedStringBuilder & ")) As BailOnly, "
strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprTotalCases FROM " & CountTable & " WHERE (" & AssignedStringBuilder & ")) As TotalCases "
strSQL += " FROM dbo.attorneys WITH (NOLOCK) LEFT OUTER JOIN dbo.tlkpunit ON dbo.attorneys.unit_id = dbo.tlkpunit.unit_id LEFT OUTER JOIN dbo.tlkpdivision ON dbo.tlkpunit.division_id = dbo.tlkpdivision.division_id LEFT OUTER JOIN dbo.tlkpoffice ON dbo.tlkpunit.office_id
= dbo.tlkpoffice.office_id WHERE (dbo.tlkpunit.unit <> 'test-unit') "
cmd = New SqlCommand(strSQL, cn)
cmd.Parameters.AddWithValue("#StartDate", DateAStart)
cmd.Parameters.AddWithValue("#EndDate", DateAEnd)
rdr = cmd.ExecuteReader()
While rdr.Read
If rdr("CasesPending").ToString = 0 And rdr("CasesAssigned") = 0 And rdr("ProbationViolation").ToString = 0 And rdr("BailOnly") = 0 Then
'Do not add record
Else
dr = dt.NewRow()
dr("CasesPending") = CInt(rdr("CasesPending"))
dr("CasesAssigned") = CInt(rdr("CasesAssigned"))
dr("ProbationViolation") = CInt(rdr("ProbationViolation"))
dr("BailOnly") = CInt(rdr("BailOnly"))
dr("TotalCases") = CInt(rdr("TotalCases"))
dr("AttorneyID") = rdr("AttorneyID")
dr("AttorneyName") = rdr("AttorneyName")
dr("UnitID") = rdr("UnitID")
dr("UnitName") = rdr("UnitName")
dr("UnitType") = rdr("UnitType")
dr("OfficeID") = rdr("OfficeID")
dr("Office") = rdr("Office")
dt.Rows.Add(dr)
End If
End While
rdr.Close()
cmd.Dispose()
If cn.State = ConnectionState.Open Then cn.Close()
Dim dv As New DataView(dt)
dv.Sort = "AttorneyName ASC"
Return dv
Read up on "sql execution plans" and you may want to review your table indexes. It is likely that these things will yield the greatest results. See this SQL Server Optimization MSDN article for more information.
I also notice in your VB code you are not parameterizing your SQL string. You should consider doing this after the above for additional performance benefit.
For more information on using SQL parameters see:
http://www.codinghorror.com/blog/2005/04/give-me-parameterized-sql-or-give-me-death.html
http://technet.microsoft.com/en-us/library/ms186219.aspx
Try using a stored procedure. This will have the code compiled in the Sql Server already and the execution plan stored ahead of time. John

how to count the record in the database?

i have this database table called people
People
peopleID peopleName relationship customerID
1 A aunty 1
2 B aunty 1
3 C second uncle 1
4 D aunty 2
how am i going to count the number of people where the customerID = 1 and if the relationship is the same, it is counted as 1
so from the database table above, i should get the result of 3 and put the result of 3 in Label1 in gridview?
i can get the count value for the only where the customerID =1 but i can't figure out how am i going to count if the relationship part
Protected Sub GridView2_RowDataBound(sender As Object, e As
System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView2.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Do your processing here...
Dim txt As TextBox = DirectCast(e.Row.FindControl("Label1"), TextBox)
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
'Dim sql As String
Dim connectionString = ConfigurationManager.ConnectionStrings("ProjData").ConnectionString
Dim myConn As New SqlConnection(connectionString)
Dim cmd = "Select * From People Where customerID='" & Session("customerID") & "' "
' Dim myCmd As New SqlCommand(cmd, myConn)
Try
myConn.Open()
Dim myCmd As New SqlCommand(cmd, myConn)
adapter.SelectCommand = myCmd
adapter.Fill(ds, "People")
adapter.Dispose()
myCmd.Dispose()
txt.Text = ds.Tables(0).Rows.Count
Catch ex As Exception
MsgBox("Can not open connection ! ")
End Try
End If
End Sub
You should wrap your SqlConnection in a using statement (not sure how you do that in VB). In your example you don't close the connection, the using statement does this for you automatically (the alternative is to close the connection in a finally block)
When i correctly understand your question, the following SQL Statement should give you the count as you need it.
Select count(peopleID)
From People
Where customerID = 1
Group by relationship, customerID
If this answer didn't solve your problem please add further information to your question.
In your code, you fetch all the rows and then count them. You can also execute a query that will count the number of rows on the server. This will perform much better!
string sql = "SELECT COUNT(*) FROM People Where customerID='" & Session("customerID") & "' "
...
int rowCount = myCmd.ExecuteScalar();
If you want to count the number of rows with the same relationship, you have to use a group by.
You have to change your sql to:
string sql = 'SELECT COUNT(peopleId) FROM People Where customerID='" & Session("customerID") & "' "GROUP BY relationship, customerId"

Resources