Update Query using two tables asp.net vb - asp.net

Please help me with this update query. I COMPLETELY understand how redundant this is but I NEED it.
Upon users creating a User account which only contains the ID, Username, Password and CustomerID I must also have a record in Customers create itself but null everything and the User.User_Customer_ID must update to the newly created Customer.Customer_ID
I have everything working but this pesky update query. The ONLY thing it needs to do is change User.User_Customer_ID to Customer.Customer_ID I managed to story the User.User_ID in an integer called UserID and Customer.Customer_ID in an integer called CustomerID I have tried a million different ways with no success
Here is what one of the many queries I have tried.
1. UPDATE [User]
SET User_Customer_ID = Customer.Customer_ID
FROM Customer
WHERE [User].User_ID = '16'
AND Customer.CUstomer_ID = '19'
( ? would be the integer UserID and CustomerID )
Here is how it looks before it is inserted into the SQL command in VB
UpdateUserCustomerID = "UPDATE [User] SET User_Customer_ID = Customer.Customer_ID FROM Customer WHERE ([User].User_ID ='" & UserID & "' AND Customer.Customer_ID = '" & CustomerID & "')"
Access Database / ASP.Net / VB
Table:
Customer:
Customer_ID
Customer_First_Name
Customer_Last_Name
Customer_Street_Address
Customer_City
Customer_State
Customer_Zip
Customer_Email
User:
User_ID
User_UserName
User_Password
User_Customer_ID

It seems pretty unlikely to me that the IDs are text fields (columns), if they are number fields, the quotes are one of the the problems.
As far as I can see, this:
"UPDATE [User] SET User_Customer_ID = Customer.Customer_ID FROM Customer WHERE ([User].User_ID ='" & UserID & "' AND Customer.Customer_ID = '" & CustomerID & "')"
Should be:
"UPDATE [User] SET User_Customer_ID = " & CustomerID _
& " WHERE ([User].User_ID = " & UserID

Related

Is this SQLite Update query correct?

String query = "UPDATE CONTACT SET NAME ='" +
contact.getName()"',phoneNO='" +
contact.getContactNumber() +
"' WHERE ID = "+contact.getId();
"UPDATE CONTACT SET NAME ='" +
contact.getName() +
"',phoneNO='" +
contact.getContactNumber() +
"' WHERE ID = " +
contact.getId();
You are missing a "+" after the getName(). But this whole approach is risky because the name and other parameters could contain quotes or other characters that could cause the statement to be parsed incorrectly (SQL injection).
It is safer to embed the query string with named parameters instead.
Like
"UPDATE CONTACT SET NAME = #name, phoneNO - #phone WHERE ID = #ID"
Then you define the values for #name, #phone, and #ID when you execute. This is much safer. The exact details of how you do that depends on the database you are using and the API

Updating Password in sql database using text-box

using ASP.NET & VB.NET i trying to update the user password, where it is equals to the sessionID
Database using is SQL Local.
here is the vb .net code
Dim pass As String
pass = tboxConFirmPass.Text
Dim connce As SqlCeConnection = New SqlCeConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ToString())
connce.Open() 'make the connection to DB
Dim sqlCommand As String = "UPDATE [tbCustomer] SET [Password] = ('" _
+ tboxConFirmPass.Text + "', '" + "WHERE [CustomerID] = #CustomerID" + "')"
Dim cmd As SqlCeCommand = New SqlCeCommand(sqlCommand, connce)
cmd.ExecuteNonQuery()
connce.Close()
MsgBox("Your Password has been chaged.")
End Sub
here is the SqlDataSource
UpdateCommand="UPDATE [tbCustomer] SET [Password] = #Password WHERE [CustomerID] = #CustomerID">
Error = There was an error parsing the query. [ Token line number = 1,Token line offset = 42,Token in error = , ]
Right, your query needs to be changed thus:
Dim sqlCommand As String = "UPDATE [tbCustomer] SET [Password] = '" _
& Replace(tboxConFirmPass.Text, "'", "''") & "' WHERE [CustomerID] = #CustomerID"
I've sorted your brackets and quotes mismatches out, changed the string concatenation operator to & and put an escape in to reduce the possibility of SQL injection vulnerability (if someone puts a single quote in their password, your query will no longer fall over, or worse).
To set a value for #CustomerID you need to add a SQL Parameter to the command object. If you don't give it a value you'll get the error mentioned in your comment. Alternatively you can concatenate the value like you do with the password:
Dim sqlCommand As String = "UPDATE [tbCustomer] SET [Password] = '" _
& Replace(tboxConFirmPass.Text, "'", "''") & "' WHERE [CustomerID] = " & CustomerID
Note that you will need to use a variable that is initialised with the ID of the customer whose password is being changed.

We would like to register a user if space is available or put on waiting list if space is full. Any ideas how to approach this?

I am trying to create a waiting list.
The idea behind this waiting list is that we have a training problem that requires users to sign up for a seat in the class.
There is a maximum capacity seating of 45 people.
If all 45 seats have been occupied, then available_seating which starts at 45 and decreases per course registration, will be 0.
If available_seating is 0, that means that the class is full and no seatings are available.
When a user attempts to sign up for a class where available_seating = 0, we would want to let the user know that this class is full and
s/he will be put on waiting list.
I think I know how to solve this problem.
When available_seating > 0 insert the user into tblTrainings table.
However, if available_seating = 0 then insert user into a table called waitingList.
My problem is how to blend that conditional statement with the counter below.
Below, the SELECT Count(*) query checks to see if user has already registered for a particular class.
If no, register the user for the class. If yes, alert the user that s/he has already registered for the class.
How do I integrate the two in such that we first check to see if the user has already registered for the class.
If no, then we check whether the class is not full yet. If full, insert user into waitingList. If not full, insert user into tblTrainings.
See current code and thanks a lot in advance.
'If user already registered for a class, alert user
s = "SELECT Count(*) FROM tblTrainings WHERE Username = '" & username & "' AND CourseID = " & Request.QueryString("cosId") & " AND LocationID = " & Request.QueryString("locid") & " AND dateId = " & Request.QueryString("iddate") & ""
Dim connSt As String = ConfigurationManager.ConnectionStrings("DBConnectionString").ConnectionString
Dim connc As New SqlConnection(connSt)
Dim cmdc As New SqlCommand(s, connc)
connc.Open()
cmdc.ExecuteNonQuery()
counter = cmdc.ExecuteScalar()
' Now let's see if we found existing record
If counter = 0 Then
'User hasn't signed up for this class yet
s = "INSERT INTO tblTrainings (CourseId, tblLocations.LocationId, dateId,AvailableSeats,username) VALUES (#CosID, #LocID, #dat, #Available_Seating, #Username)"
Dim cmd = New SqlCommand(s, conn)
cmd.Parameters.AddWithValue("#cosID", Request.QueryString("cosId"))
cmd.Parameters.AddWithValue("#locID", Request.QueryString("locid"))
cmd.Parameters.AddWithValue("#dat", Request.QueryString("iddate"))
cmd.Parameters.AddWithValue("#Available_Seating", 45 - 1)
cmd.Parameters.AddWithValue("#UserName", username)
conn.Open()
Maybe I'm missing something, but it doesn't seem that complicated to me.
This answer only uses the SQL pieces that matter to preserve legibility, since I'm mainly referring to queries and not the VB.
First, you do what you were already doing--check to see if they're already signed up/on the waiting list.
SELECT Count(*) FROM (
SELECT * FROM tblTrainings UNION SELECT * FROM waitingList
) AS t
WHERE Username = XXX AND CourseID = XXX AND LocationID = XXX AND dateID = XXX
/* Tells you whether the person is signed up already, whether for the course itself
or the waiting list. */
SELECT Count(*) FROM tblTrainings
WHERE CourseID = XXX AND LocationID = XXX AND dateID = XXX
-- This will give you the number of people in the course.
Then, once you have that, you can decide whether to add them to that table or add them to waiting list.
Update
Maybe this will help.
'Here build your querystring s from the SQL query above, filling in whatever values your need.
s = "SELECT Count(*) FROM (" & _
"SELECT * FROM tblTrainings UNION SELECT * FROM waitingList" & _
") AS t" & _
"WHERE Username = XXX AND CourseID = XXX AND LocationID = XXX AND dateID = XXX"
Dim connSt As String = ConfigurationManager.ConnectionStrings("DBConnectionString").ConnectionString
Dim connc As New SqlConnection(connSt)
Dim cmdc As New SqlCommand(s, connc)
connc.Open()
cmdc.ExecuteNonQuery()
counter = cmdc.ExecuteScalar()
If counter = 0 Then 'this means that the person is in neither the waitlist nor courselist
'Fill in the XXX as necessary
qs = "SELECT Count(*) FROM tblTrainings WHERE CourseID = XXX AND LocationID = XXX AND dateID = XXX"
Set cmdc = New SqlCommand(s, connc)
cmdc.ExecuteNonQuery()
courseSize = cmdc.ExecuteScalar()
If courseSize <= 45 Then
'Insert the guy into the course
Else
'Insert the guy into waitList
End If
End If
Let's say you have a TableA and you want to insert a record only when TableB count is zero. Then you could write this:
insert into TableA (ColA, ColB)
select 'a', 'b' from TableB
where 0 = (select count(*)
from TableB
where ColC = 'c')
It should be easy to fit the above statement to your scenario.

Inserting into multiple tables using more than one ID that just got created

I had to add another table into my database and now I need to go back and update a page that allows inserts into more than one table. I didn't write this page, so I'm trying to clean everything up, but there are some parts that I don't really understand. Now I have broken the page and it only inserts into one table. The very first one that I insert into.
ProductName: goes into the Product table
Description: goes into the Picklist table as Data.....it also is supposed to generate an insert into the marketing table based on the PicklistID which is an identity column. The marketing table tells the Picklist table that it is looking for a description.
Price: goes into Product table
Category: goes into the CategoryLink table which also inserts the recently generated ProductID.
Company: goes into the CompanyLink table which also inserts the recently generated ProductID.
Target audience: goes into the TargetLink table which also inserts the recently generated ProductID.
Status: goes into the Product table
Protected Sub submitButton_Click(ByVal sender As Object,
ByVal e As System.EventArgs) Handles submitButton.Click
Dim CategoryID As String = txtCategoryID.Value
Dim CompanyIDs As New ArrayList
'Get selected companies-----
Dim CompanyCount As Integer = CompanyCheckbox.Items.Count
For i As Integer = 0 To CompanyCount - 1
If CompanyCheckbox.Items(i).Selected Then
CompanyIDs.Add(CompanyCheckbox.Items(i).Value)
End If
Next
'Get selected targets---
Dim TargetIDs As New ArrayList
Dim TargetCount As Integer = TargetCheckbox.Items.Count
For i As Integer = 0 To TargetCount - 1
If TargetCheckbox.Items(i).Selected Then
TargetIDs.Add(TargetCheckbox.Items(i).Value)
End If
Next
'Get Status---
Dim Status As String = Nothing
If StatusCheckbox.Checked Then
Status = "1"
Else
Status = "0"
End If
'SQL Insert: Product Table
Dim sqlInsertProduct As String = "IF NOT EXISTS (SELECT * FROM Product
WHERE ProductName= #ProductName)
BEGIN INSERT INTO Product
(ProductName, Status, CreateDate, ModifyDate, CreateUser, ModifyUser, Price)
VALUES (#ProductName, #Status ,getdate(),getdate(), #CreateUser, #ModifyUser,
#Price) END;
INSERT INTO Picklist (Title, Data) VALUES ('About this product', #Data);"
'Create SQL Connection
Using cn As New
SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings
("LocalSqlServer").ConnectionString)
Using cmd As New SqlCommand(sqlInsertProduct, cn)
cmd.Parameters.Add(New SqlParameter("#ProductName",
txtNewProductName.Text))
cmd.Parameters.Add(New SqlParameter("#Status", StatusCheckbox.Checked))
cmd.Parameters.Add(New SqlParameter("#Price", txtPrice.Text))
cmd.Parameters.Add(New SqlParameter("#Data", txtProductDesc.Text))
cmd.Parameters.Add(New SqlParameter("#CreateUser",
System.Web.HttpContext.Current.User.Identity.Name))
cmd.Parameters.Add(New SqlParameter("#ModifyUser",
System.Web.HttpContext.Current.User.Identity.Name))
cn.Open()
cmd.ExecuteNonQuery()
End Using
'Get the productID of the newly inserted product
Dim sqlGetID As String = "SELECT ##IDENTITY"
Dim ProductID As String = Nothing
Dim cmdGetID As New SqlCommand(sqlGetID, cn)
Dim myReader As SqlDataReader = cmdGetID.ExecuteReader()
While myReader.Read
If IsDBNull(myReader(0)) Then
ProductID = ""
Else
ProductID = myReader(0)
End If
End While
myReader.Close()
cn.Close()
'SQL Insert: Marketing Table
Dim sqlInsertMarketing As String = "INSERT INTO Marketing (ProductID,
MarketingTypeID, MarketingTitle, MarketingData) VALUES ('" & ProductID & "', 2,
'Description', scope_identity())"
'SQL Insert: Category Table
If CategoryID <> Nothing Then
Dim sqlInsertCategory As String = "INSERT INTO CategoryLink (CategoryID,
ProductID) VALUES (#CategoryID,'" & ProductID & "')"
Using cmdInsertCategory As New SqlCommand(sqlInsertCategory, cn)
cmdInsertCategory.Parameters.Add(New SqlParameter("#CategoryID",
txtCategoryID.Value))
cn.Open()
cmdInsertCategory.ExecuteNonQuery()
End Using
cn.Close()
End If
If CompanyIDs.Count > 0 Then
For i = 0 To CompanyIDs.Count - 1
Dim sqlInsertCompany = "INSERT INTO CompanyLink (CompanyID, ProductID)
VALUES ('" & CompanyIDs(i) & "','" & ProductID & "')"
Using cmdInsertCompany As New SqlCommand(sqlInsertCompany, cn)
cn.Open()
cmdInsertCompany.ExecuteNonQuery()
End Using
cn.Close()
Next
End If
If TargetIDs.Count > 0 Then
For i = 0 To TargetIDs.Count - 1
Dim sqlInsertTarget = "INSERT INTO TargetLink (TargetID, ProductID)
VALUES ('" & TargetIDs(i) & "','" & ProductID & "')"
Using cmdInsertTarget As New SqlCommand(sqlInsertTarget, cn)
cn.Open()
cmdInsertTarget.ExecuteNonQuery()
End Using
cn.Close()
Next
End If
End Using
Response.Write("<script type='text/javascript'>{ alert('Product added successfully');
document.location.href = 'AddProduct.aspx'; }</script>")
End Sub
End Class
Like I said before, only the insert that goes into the Product table works. Before I added the Picklist table and tried to reconnect everything, this entire page worked. The code was a lot sloppier and didn't have parameters, so that could also be where I messed up since I am still trying to learn how to use them. If I need to include additional information I can do that. I don't know how detailed to make this post. Thanks
UPDATE:
I have gotten everything to INSERT except for the INSERT to the Marketing table. I would really appreciate someone who can help me get that PicklistID to insert into the MarketingData column of the Marketing table
If you only have one identity value to get use SCOPE_IDENTITY(), never use ##IDENTITY. The problem with ##IDENTITY is that it always returns the last identity value, even if it was from another "scope". For example, you insert into your table and an identity value is generated, a trigger then fires that inserts in to a log table with an identity. You then call ##IDENTITY, guess what you get the log table identity value, it was last. SCOPE_IDENTITY() gives you the last within your local scope.
HOWEVER, if you need to capture multiple identity values because you insert multiple rows in one statement, you must use the OUTPUT clause. It works on INSERT, UPDATE and DELETE, but here is an example on an UPDATE: view the changed values after an update statement
This is one of the drawbacks of surrogates i.e. harder to perform bulk-creation of entities. I avoid using surrogates myself but often come up against this problem. My general approach is to use a staging table to map system-generated surrogates to their natural keys.
Assuming this somewhat simplified structure:
CREATE TABLE Products
(
ProductName VARCHAR(20) NOT NULL UNIQUE, -- natural key
ProductID INTEGER IDENTITY(1, 1) NOT NULL UNIQUE -- surrogate
);
CREATE TABLE PickLists
(
PicklistDescription VARCHAR(30) NOT NULL UNIQUE, -- natural key
PicklistID INTEGER IDENTITY(50, 50) NOT NULL UNIQUE -- surrogate
);
CREATE TABLE Marketing
(
ProductID INTEGER NOT NULL UNIQUE REFERENCES Products (ProductID),
PicklistID INTEGER NOT NULL UNIQUE REFERENCES PickLists (PicklistID),
MarketingComment VARCHAR(40) NOT NULL
);
the following is a basic outline using vanilla Standard SQL-92 (IDENTITY keyword excepted!):
(note: natural keys are those generated outside of the DBMS and surrogates are DBMS-generated values)
CREATE TABLE StagingMarketing
(
ProductName VARCHAR(20) NOT NULL UNIQUE,
PicklistDescription VARCHAR(30) NOT NULL UNIQUE,
MarketingComment VARCHAR(40) NOT NULL
);
-- Bulk insert staging table using natural key values
INSERT INTO StagingMarketing (ProductName, PicklistDescription, MarketingComment)
VALUES ('Widget55', 'Stuff22', 'Prototype');
INSERT INTO StagingMarketing (ProductName, PicklistDescription, MarketingComment)
VALUES ('Widget99', 'Stuff152', 'Research');
-- Update referenced tables
INSERT INTO Products (ProductName)
SELECT ProductName FROM StagingMarketing;
INSERT INTO PickLists (PicklistDescription)
SELECT PicklistDescription FROM StagingMarketing;
-- Finally, update referencing table
INSERT INTO Marketing (ProductID, PicklistID, MarketingComment)
SELECT P.ProductID, L.PicklistID, S.MarketingComment
FROM StagingMarketing S
INNER JOIN Products P
ON P.ProductName = S.ProductName
INNER JOIN PickLists L
ON L.PicklistDescription = S.PicklistDescription;
-- Cleanup
DELETE FROM StagingMarketing;
SELECT * FROM Marketing;
p.s. if the designer chose to use IDENTITY as an artificial key in absence of a natural key then you are up the creek.

DataReader already open error when trying to run two queries

I have a couple of queries that I need to run one to a linked server and one not like this
Dim InvestorLookup As String = "DECLARE #investor varchar(10), #linkedserver varchar(25), #sql varchar(1000) "
InvestorLookup += "SELECT #investor = '" & investor & "', #linkedserver = '" & db & "', "
InvestorLookup += "#sql = 'SELECT * FROM OPENQUERY(' +#linkedserver + ', ''SELECT * FROM db WHERE investor = ' + #investor + ' '')' EXEC(#sql)"
Dim queryInvestorLookup As SqlCommand = New SqlCommand(InvestorLookup , conn)
Dim BondNoDR As SqlDataReader = queryInvestorLookup.ExecuteReader()
Dim PasswordCheck As String = "DECLARE #investor varchar(10), #password varchar(20), #linkedserver varchar(25), #sql varchar(1000) "
PasswordCheck += "SELECT #investor = '" + investor + "', #password = '" + password + "', #server = '" + db2 + "', "
PasswordCheck += "#sql = 'SELECT * FROM #server WHERE investor = #investor AND password = ' + #password + ' '' EXEC(#sql)"
Dim queryPasswordCheck As SqlCommand = New SqlCommand(PasswordCheck, conn)
Dim PasswordDR As SqlDataReader = queryPasswordCheck.ExecuteReader()
As far as I can tell from debugging the queries both run as they should but I get the error
There is already an open DataReader associated with this Command which must be closed first.
Is it possible to run two queries in two different DataReaders. I need to later reference each DataReader and select values from each.
By default it´s not possible to have two SqlDataReader's open at the same time sharing the same SqlConnection object. You should close the first one (queryInvestorLookup) before calling the second (queryPasswordCheck).
This would be good from a design and performance point of view since a recommendation for .NET is that every unmanaged resource (like database access) is opened as later as possible and closed early as possible.
Another way would be to enable MARS but afaik it is only available for Sql2005 and up.
The third solution would be to use the same SqlDataReader to issue the two queries and then navigate through then using NextResults() method.
If the provider that you are using supports it, you can enable MARS (Multiple Active Result Sets) by adding MultipleActiveResultSets=True to the connection string that you are using.
By default you can't have to dataReaders open on the same connection. So you could get one result, stuff it in a DataTable and then get the other result. Or you could turn on MARS
ADO.NET Multiple Active Resut Sets

Resources