How To Prevent This Exception? - vb.net

what i got:
two mdb databases and one application to insert information (rows) from db1 to db2.
when i'am runing my code there is an exception:
System resource exceeded.
the code:
Connection Strings:
Dim db2Connection As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db2.mdb;Persist Security Info=False;")
Dim db1Connection As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\db1.mdb;Persist Security Info=False;")
Code to copy the information:
Dim DataAddapter As New OleDb.OleDbDataAdapter
Dim ds As New DataSet
'Open DB1 Connection:
db1Connection.open()
'Select All From M
DataAddapter.SelectCommand = New OleDb.OleDbCommand("SELECT * FROM M", db1Connection)
Dim cmd As OleDb.OleDbCommand = DataAddapter.SelectCommand
Dim Reader As OleDb.OleDbDataReader = cmd.ExecuteReader()
'Before Reading Results From DB1 Lets Open DB2Connection:
db2Connection.open()
'Start Reading Results in LOOP:
Do Until Reader.Read() = False
Dim F_Name As String = Reader("F_NAME")
Dim L_Name As String = Reader("L_NAME")
Dim CITY As String = Reader("NAME_CITY")
F_Name = Replace(F_Name, "'", "")
L_Name = Replace(L_Name, "'", "")
'Start Moving The Results To Db2(Insert):
'--------------------------------------
Dim Exist As Integer = 0
Dim c As New OleDb.OleDbCommand
c.Connection = db2Connection
c.CommandText = "SELECT COUNT(*) FROM `Names` WHERE `LastName`='" & L_Name & "' AND `FirstName`='" & F_Name & "' AND `City`='" & CITY & "'"
'----------------------------------------
'Exception Here!! :(
'This Line Checking If Already Exist
Exist = CLng(c.ExecuteScalar())
'----------------------------------------
If Exist = 0 Then
c.CommandText = "INSERT INTO `Names` (`LastName`,`FirstName`,`City`) VALUES ('" & L_Name & "','" & F_Name & "','" & CITY & "')"
c.ExecuteNonQuery()
'Note: After this line i'am getting the Exception there... (2 queries executed ExecuteScalar + ExecuteNonQuery) maybe i need to create connection for every query? :S
End If
Loop
another thing:
i have to send the query to db2 in this syntax(Otherwise it does not work):
INSERT INTO `Names` (`LastName`,`FirstName`,`City`) VALUES ('" & L_Name & "','" & F_Name & "','" & CITY & "')
i have to use the -> ` <- to the name of the columns,
but when i'am sending a query to db1 without -> ` <- it's working. :S and i dont know what is the difference between db1 to db2 but its very strange maybe my problem is there...
good answer is a good example plus good explanation :).(c# or vb.net)

You are prime for sql-injection... You should read-up on that, and at a minimum, PARAMETERIZE your sql commands, do NOT build string statement to execute with embedded values. I don't specifically know how db2 handles parameters... some use "?" as place-holders, SQL-Server uses "#" and Advantage Database uses ":".. but in either case, here is the principle of it...
c.CommandText = "select blah from `names` where LastName = ? and FirstName = ? and City = ?"
c.CommandText = "select blah from `names` where LastName = #parmLastName and FirstName = #parmFirstName and City = #parmCity"
For the named parameters above (such as #parmLastName), I am prefixing with "parm" for sole purpose of differentiating a value vs the actual COLUMN name
Then, your parameters would be something like
c.Parameters.Add( "#parmLastName", yourLastNameVariable )
c.Parameters.Add( "#parmFirstName", yourFirstNameVariable)
c.Parameters.Add( "#parmCity", yourCityVariable)
If using the "?" version of parameters where they are not explicitly named, you need to just make sure your parameter context is in the same sequence as the "?" place-holders.
Then execute your call... Same principle would apply for all your queries (select, insert, update, delete)
As for your system resources... how many records are you pulling down. It could just be choking your system memory resources trying to pull down the entire database table. You might want to break down based on one alphabetic letter at a time...
Also, a link from MS about system resources and Access via a patch.

Related

Receiving an error when attempting to update a record

In my program I have a function titled runSQL, here it is:
Dim Connection As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TrainingLog.accdb")
Dim DT As New DataTable
Dim DataAdapter As OleDb.OleDbDataAdapter
Connection.Open()
DataAdapter = New OleDb.OleDbDataAdapter(query, Connection)
DT.Clear()
DataAdapter.Fill(DT)
Connection.Close()
Return DT
And I'm trying to update a record in a database using the update string, sourced from this code:
Dim sqlString As String
sqlString = "UPDATE UserRecords set FirstName = '" & txtName.Text
sqlString = sqlString & "', LastName = '" & txtSurname.Text
If ChkSmoker.Checked = True Then
sqlString = sqlString & "', Smoker = true"
ElseIf ChkSmoker.Checked = False Then
sqlString = sqlString & "', Smoker = false"
End If
sqlString = sqlString & ", Weight = " & txtWeight.Text
If RdoMale.Checked = True Then
sqlString = sqlString & ", Gender = 'm'"
ElseIf RdoFemale.Checked = True Then
sqlString = sqlString & ", Gender = 'f'"
End If
sqlString = sqlString & " WHERE UserName = '" & LstUsers.SelectedItem.ToString & "'"
runSQL(sqlString)
However once I click the save button, I get an error from line 7 of the runSQL function (not including empty line, so that's the DataAdapter.Fill(DT) line) which says "No value given for one or more required parameters."
I wondered if anyone knew why this is or how to fix it.
One thing I did think of is that, in the table being updated, there are fields other than those being mentioned in my UPDATE statement. For example there is a Yes/no field titled "TeamMember", which I don't mention in the update statement.
When using the update function, do I have to give values for every field, even those not being changed?
Thanks for reading, and hopefully helping!
You should never composea SQL query yourself. It much easies and safer (to vaoid SQL injection) to create a parameterized query, or use an stored procedure. And then execute it by pasing the query or stored procedure name and the parameter values.
Besides, in this way, you don't have to take care of what the right format is for a particular value. For example, how do you format a date? And, how do you format a boolean value? Most probably the problem with your query is the false or true value that you're trying to set for the Smoker column, because in TSQL that's a bit value, and can only be 0 or 1.
Check this to see samples of using parameters: ADO.NET Code Examples (Click the VB tab to see it in VB). You'll see that you define a parameter specifying a name with an # prefix in the query, and then you simply pass a value for each parameter in the query, and it will be passed to the server in the correct format without you taking care of it.
Taken from one of the samples:
Dim queryString As String = _
"SELECT ProductID, UnitPrice, ProductName from dbo.Products " _
& "WHERE UnitPrice > #pricePoint " _
& "ORDER BY UnitPrice DESC;"
Dim command As New SqlCommand(queryString, connection)
command.Parameters.AddWithValue("#pricePoint", paramValue)
'' command.ExecuteXXX
NOTE that you can execute the command in different ways, depending on your need to simply execute it or get an scalar value or a full dataset as a result.

how to check duplicate record before insert, using vb.net and sql?

can someone help me with my code, i need to check first if record exist. Well i actually passed that one, but when it comes to inserting new record. im getting the error "There is already an open DataReader associated with this Command which must be closed first." can some help me with this? thanks.
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim reg_con As SqlConnection
Dim reg_cmd, chk_cmd As SqlCommand
Dim checker As SqlDataReader
Dim ID As Integer
Dim fname_, mname_, lname_, gender_, emailadd_, college_, password_ As String
ID = idnumber.Value
fname_ = fname.Value.ToString
mname_ = mname.Value.ToString
lname_ = lname.Value.ToString
gender_ = gender.Value.ToString
college_ = college.Value.ToString
emailadd_ = emailadd.Value.ToString
password_ = reg_password.Value.ToString
reg_con = New SqlConnection("Data Source=JOSH_FLYHEIGHT;Initial Catalog=QceandCceEvaluationSystemDatabase;Integrated Security=True")
reg_con.Open()
chk_cmd = New SqlCommand("SELECT IDnumber FROM UsersInfo WHERE IDnumber = '" & ID & "'", reg_con)
checker = chk_cmd.ExecuteReader(CommandBehavior.CloseConnection)
If checker.HasRows Then
MsgBox("Useralreadyexist")
Else
reg_cmd = New SqlCommand("INSERT INTO UsersInfo([IDnumber], [Fname], [Mname], [Lname], [Gender], [Emailadd], [College], [Password]) VALUES ('" & ID & "', '" & fname_ & "', '" & mname_ & "', '" & lname_ & "', '" & gender_ & "', '" & emailadd_ & "', '" & college_ & "', '" & password_ & "')", reg_con)
reg_cmd.ExecuteNonQuery()
End If
reg_con.Close()
End Sub
Add this string to your connection string
...MultipleActiveResultSets=True;";
Starting from Sql Server version 2005, this string allows an application to maintain multiple active statements on a single connection. Without it, until you close the SqlDataReader you cannot emit another command on the same connection used by the reader.
Apart from that, you insert statement is very dangerous because you use string concatenation. This is a well known code weakness that could result in an easy Sql Injection vulnerability
You should use a parameterized query (both for the insert and for the record check)
reg_cmd = New SqlCommand("INSERT INTO UsersInfo([IDnumber], ......) VALUES (" & _
"#id, ......)", reg_con)
reg_cmd.Parameters.AddWithValue("#id", ID)
.... add the other parameters required by the other field to insert.....
reg_cmd.ExecuteNonQuery()
In a parameterized query, you don't attach the user input to your sql command. Instead you put placeholders where the value should be placed (#id), then, before executing the query, you add, one by one, the parameters with the same name of the placeholder and its corresponding value.
You need to close your reader using checker.Close() as soon as you're done using it.
Quick and dirty solution - issue checker.Close() as a first command of both IF and ELSE block.
But (better) you don't need a full blown data reader to check for record existence. Instead you can do something like this:
chk_cmd = New SqlCommand("SELECT TOP (1) 1 FROM UsersInfo WHERE IDnumber = '" & ID & "'", reg_con)
Dim iExist as Integer = chk_cmd.ExecuteScalar()
If iExist = 1 Then
....
This approach uses ExecuteScalar method that returns a single value and doesn't tie the connection.
Side note: Instead of adding parameters like you do now - directly to the SQL String, a much better (and safer) approach is to use parametrized queries. Using this approach can save you a lot of pain in the future.

Q. How to dynamically add queries to a table adapter in Visual Studio

I have setup a Table Adapter in Visual Studio linked to a SQL Server db.
I've followed the MSDN tutorials and I have manually setup some queries for this TA. I think of these queries as "pre_hardcoded". I call these queries using the default code:
Me.ItemFactTableAdapter.My_Pre_Hardcoded_Query(Me.MasterDataSet.ItemFact)
I want to dynamically call data in different configuration (from the same Master Table) and thus I need a lot of these pre-hardcoded queries. So, instead of writing 1k queries I've want to use something like this:
TableName = "ItemFact"
H_Label = "ChainName"
V_Label = "ItemName"
Dim Measure As String = "Volume"
Dim Select_Clause As String = "select distinct " & H_Label & "," & V_Label & ", Sum(" & Measure & ") as " & Measure & " "
Dim From_Clause As String = "from " & TableName & " "
Dim Where_Clause As String = ""
Dim GroupBy_Clause As String = "group by " & H_Label & "," & V_Label
Dim SelectionQuery = Select_Clause & From_Clause & Where_Clause & GroupBy_Clause
Where I can dynamically update the values of "Measure" and the "H" & "V Labels".
The question is: How do I declare this SelectionQuery to be a valid part of the TA so that I can use it like:
Me.ItemFactTableAdapter.SelectionQuery (Me.MasterDataSet.ItemFact)
for dynamic query you need create generic DataAdapter:
Dim da As New SqlDataAdapter(SelectionQuery, Me.ItemFactTableAdapter.Connection)
da.Fill(Me.MasterDataSet.ItemFact)
I still haven't found an answer to my initial question ON HOW TO ADD QUERIES TO A TABLE ADAPTER, but based on #lomed answer I've done a workaround. Thus, instead of filling the TA on 1st load and then pulling data with different queries, I'm updating the whole dataset on each query. I believe this method may be more time-consuming when applied to big datasets, but for now it works.
Dim strConn As String = "Data Source=XXX;Initial Catalog=master;Integrated Security=True"
Dim conn As New SqlConnection(strConn)
Dim oCmd As New SqlCommand(SelectionQuery, conn)
Dim oData As New SqlDataAdapter(SelectionQuery, conn)
Dim ds As New DataSet
and then attach the dataset to objects like:
Chart1.DataSource = ds.Tables("Table1")
instead of:
Chart1.DataSource = Me.ItemFactBindingSource

how to insert a row to my db table from vb.net

am using vb.net, and i want to insert a row to my db Table "adwPays" from my windows form.
this is my code:
Dim CC, EngName, FreName, LanCode As String
Dim DialCode As Integer
CC = txtCC.Text
EngName = txtEN.Text
FreName = txtFN.Text
LanCode = txtLC.Text
DialCode = txtDC.Text
Dim MyConn As New SqlConnection("Server=(local);Database=dbAjout;Integrated Security=True")
Dim query As String
query = "INSERT INTO adwPays (CC, Anglais,Francais,CodeLangue,IndicInter) VALUES ( ' " & CC & "','" & EngName & "','" & FreName & "','" & LanCode & "','" & DialCode & " ');"
Dim cmd As New SqlCommand(query, MyConn)
MyConn.Open()
cmd.ExecuteScalar()
MyConn.Close()
BUT its giving me this error
"An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: String or binary data would be truncated.
The statement has been terminated."
any help?
Use a parameterized query like this
Dim query = "INSERT INTO adwPays (CC, Anglais,Francais,CodeLangue,IndicInter) " &
"VALUES (#cc, #ename, #fname, #lan, #dial)"
Using MyConn = New SqlConnection("Server=(local);Database=dbAjout;Integrated Security=True")
Using cmd = New SqlCommand(query, MyConn)
cmd.Parameters.AddWithValue("#cc", CC)
cmd.Parameters.AddWithValue("#ename", EngName)
cmd.Parameters.AddWithValue("#fname", FreName)
cmd.Parameters.AddWithValue("#lan", LanCode)
cmd.Parameters.AddWithValue("#dial", DialCode)
MyConn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Using a parameterized query allows to avoid problems with Sql Injections and clears the command text from the formatting quotes around strings and dates and also let the framework code pass the correct decimal point for the numeric types when need
I have also added a Using Statement around the SqlConnection and the SqlCommand to be sure that the objects are closed and destroyed. The parameters are all passed as strings, this could be wrong if any of your database fields are not of text type.
It sounds like you have a String value that is longer than the database type size allows. Can you verify the type and size of each of the following fields:
cc
ename
fname
lan
Now cross-reference those sizes with what the values are in the textbox fields you are pulling them from in the UI.
My money is on one of those exceeding the database size limits.
If that is the case, then you need to introduce length checking before you attempt to save to the database.

VB.NET: convert text with single quote to upload to Oralce DB

I have a function in VB.NET that runs a query from an MS SQL DB, puts the results into temporary variables, then updates an Oracle DB. My question is, if the string in the MS SQL contains a single quote ( ' ), how do I update the Oracle DB for something that has that single quote?
For example: Jim's request
Will produce the following error: ORA-01756: quoted string not properly terminated
The ueio_tmpALM_Comments (coming from MS SQL) is the culprit that may or may not contain the single quote.
update_oracle =
"update Schema.Table set ISSUE_ADDED_TO_ALM = '1'," & _
"ISSUE_COMMENTS = '" & ueio_tmpALM_Comments & "'," & _
"where ISSUE_SUMMARY = '" & ueio_tmpALM_Summary & "' "
Dim or_cmd_2 = New NetOracle.OracleCommand(update_oracle, OracleConn)
or_cmd_2.ExecuteNonQuery()
From your question it's clear that you are building the update query using string concatenation.
Something like this
Dim myStringVar as string = "Jim's request"
Dim sqlText as String = "UPDATE MYTABLE SET MYNAME = '" + myStringVar + "' WHERE ID = 1"
this is a cardinal sin in the SQL world. Your code will fail for the single quote problem, but the most important thing is that this code is subject to Sql Injection Attacks.
You should change to something like this
Dim cmd As OraclCommand = new OracleCommand()
cmd.Connection = GetConnection()
cmd.CommandText = "UPDATE MYTABLE SET MYNAME = :myName WHERE ID = 1"
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue(":myName", myStringVar)
cmd.ExecuteNonQuery()