Try Catch Exception running SQL Query Twice - asp.net

This function seems to be running the SQL query twice, any idea why?
When I run an insert SQL query it inserts the data but also brings back this error:
Violation of PRIMARY KEY constraint 'PK__SD_T_Cod__143F51C51BFD2C07'.
Cannot insert duplicate key in object 'dbo.SD_T_Code'. The duplicate
key value is (t-503).
This seems to tell me that it is running the SQL twice, it gets inserted the first time, but the second time it doesn't insert because the id already exists (it got created with the first insert)
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
Dim connStr As String = ConfigurationManager.ConnectionStrings("dbConnect").ConnectionString
Dim con As New SqlConnection(connStr)
cmd.CommandType = CommandType.Text
cmd.Connection = con
Try
con.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
'resultSQL.Text = ex.Message
Return False
Finally
resultSQL.Text = "Successfully Saved"
con.Close()
con.Dispose()
End Try
End Function
End Class

Related

Error parsing - Insert value Textbox inside database

I have this form ASP.NET that have two textbox and a label, where the user enters only the expiration date in the last textbox, while the others are inserted automatically if the user clicks on another button inside the repeater where the customer code and company name are found.
The problem is that I created a class to do the insertion: I used a stored procedure for the insertion and I used the query parameterization.
When I parse the code and date it gives me 0 and a default date as a result, while my goal is to insert them into a table inside a db and then have it displayed inside the repeater.
P.S. I add that for reading the data I have another class with another stored procedure and that I have some values ​​that are inside another table (the code and the name of the company).
This is the method:
Public Sub INSERT_EXP_DATE_TABLE()
Dim id_customer As Integer
Dim exp_date As Date
Try
cmd.Connection = cn
cmd.CommandType = CommandType.StoredProcedure
MyParm = cmd.Parameters.Add("#COD_CUSTOMER", SqlDbType.Int)
If (Integer.TryParse(txt_COD_CUSTOMER.Text, id_customer)) Then
MyParm.Value = id_customer
Else
MsgBox("customer not found", vbCritical)
End If
MyParm = cmd.Parameters.Add("#COMPANY_NAME", SqlDbType.NVarChar)
MyParm.Value = lbl_COMPANY_NAME.Text.ToString
MyParm = cmd.Parameters.Add("#EXP_DATE", SqlDbType.Date)
If (Date.TryParse(txt_EXP_DATE.Text, exp_date)) Then
MyParm.Value = exp_date
Else
MsgBox("Exp Date not found", vbCritical)
End If
cmd.CommandText = "LST_INSERT_TABLE_01"
cmd.Connection.Open()
cmd.ExecuteNonQuery()
MsgBox("Date registred", vbInformation)
Catch ex As Exception
MsgBox(ex.Message)
Finally
cn.Close()
End Try
End Sub
And this is the stored procedure:
#ID_CUSTOMER int,
#COMPANY_NAME varchar(50),
#EXP_DATE date,
AS
BEGIN
INSERT INTO TABLE
(
ID_CUSTOMER,
COMPANY_NAME,
EXP_DATE,
)
VALUES(
#ID_CUSTOMER,
#COMPANY_NAME,
#EXP_DATE,
)
END
Keep your connection local to the method where it is used. Connections use unmanaged resources so they include a .Dispose method which releases these resources. To ensure that the database objects are closed and disposed use Using...End Using blocks.
Do you parsing before you start creating database objects. Exit the sub so the user has a chance to correct the problem.
Side note: I don't think a message box will work in an asp.net application.
You set up the company name parameter as an NVarChar but your stored procedure declares it as a VarChar. Which is correct?
It is not necessary to call .ToString on a .Text property. A .Text property is already a String.
You are providing a parameter called "#COD_CUSTOMER" but your stored procedure does not have such parameter.
Public Sub INSERT_EXP_DATE_TABLE()
Dim id_customer As Integer
If Not Integer.TryParse(txt_COD_CUSTOMER.Text, id_customer) Then
MsgBox("Please enter a valid number.", vbCritical)
Exit Sub
End If
Dim exp_date As Date
If Not Date.TryParse(txt_EXP_DATE.Text, exp_date) Then
MsgBox("Please enter a valid date.")
Exit Sub
End If
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("LST_INSERT_TABLE_01", cn)
cmd.CommandType = CommandType.StoredProcedure
With cmd.Parameters
.Add("#ID_CUSTOMER", SqlDbType.Int).Value = id_customer
.Add("#COMPANY_NAME", SqlDbType.VarChar, 50).Value = lbl_COMPANY_NAME.Text
.Add("#EXP_DATE", SqlDbType.Date).Value = exp_date
End With
Try
cn.Open()
cmd.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Sub
{
string CN = Interaction.InputBox("Enter Company Name","Customer","",-1,-1);
string Cname = Interaction.InputBox("Enter Customer Name", "Customer", "", -1, -1);
SqlConnection con = new SqlConnection(#"Data Source=Adnan;Initial Catalog=Production;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO hello(Company_Name,Customer_name ) VALUES ( #Company_Name,#Customer_name )");
cmd.Connection = con;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#Company_Name", CN.ToString() );
cmd.Parameters.AddWithValue("#Customer_name", Cname.ToString());
}

Attempting to load a datatable - Operation is not valid due to the current state of the object

I'm trying to connect & query an Oracle DB and load the results into a datatable but I keep getting the 'operation is not valid due to the current state of the object' error for the code below:
Using conn As New OracleConnection(oradb)
Try
cmd = New OracleCommand()
da = New OracleDataAdapter(cmd)
dteDTK = New DataTable()
conn.Open()
cmd.CommandText = "SELECT * FROM TABLE1"
cmd.CommandType = CommandType.Text
da.Fill(dteDTK)
Catch ex As OracleException
MessageBox.Show(ex.Message.ToString())
Finally
conn.Close()
conn.Dispose()
End Try
End Using
The error throws on the 'da.Fill(dteDTK)' command. What am I missing here?
You are not assigning the Connection to the Command. I would imagine that you need to do this on OracleCommand:
cmd.Connection = conn
Otherwise, you are executing a SQL statement on a command that has no connection associated.

database update sql not affecting database

i have this code to update a database, but when ever i run it with the right data, it executes without errors but the databse is not update
Dim conn As New SqlClient.SqlConnection(My.Resources.conn_str)
Dim SQL As String = "Update vehicle SET make=#make,reg_no=#reg_no,model=#model,year=#year,type=#type,last_service=#last_service Where (id = #id)"
conn.Open()
Try
Dim cmd As New SqlClient.SqlCommand(SQL, conn)
Try
cmd.Parameters.AddWithValue("#make", strMake)
cmd.Parameters.AddWithValue("#reg_no", strRegnNum)
cmd.Parameters.AddWithValue("#model", strModel)
cmd.Parameters.AddWithValue("#year", intYear)
cmd.Parameters.AddWithValue("#type", strType)
cmd.Parameters.AddWithValue("#last_service", LastService)
cmd.Parameters.AddWithValue("#id", ID.ToString)
cmd.ExecuteNonQuery()
cmd.Dispose()
Catch ex As Exception
Return ex.Message
End Try
Catch ex As Exception
Return ex.Message
Finally
conn.Dispose()
End Try
can anyone help me with the reason its not working, as i don get an error message?
thanks
EDIT
i replaced the cmd.ExecuteNonQuery() with
Dim intAffected As Integer = cmd.ExecuteNonQuery()
Debug.Print(intaffected)
and i get 1 in the output window
A few thoughts:
If you have access to SQL Profiler, you can see the query, the values, the result, any triggers, any transactions, etc. This is the easiest way to identify what is going on.
If you don't have access to Profiler, update your query to include the OUTPUT clause, and return the values from inserted.* and deleted.* into a SqlDataReader using ExecuteReader. Check the results.
If the id is an int, don't use ID.ToString() on the parameter.AddWithValue. Use the integer itself, as the AddWithValue method with a string value could cause the ID parameter to be configured as a varchar/nvarchar.

SQL Server CE does not support DataReader.HasRows?

I have the following code;
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
If rdr.HasRows Then
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
End If
The error I get is:
SQL Server Compact does not support calls to HasRows property if the
underlying cursor is not scrollable.
So how am I supposed to check if data exists before actually reading the DataReader?
EDIT
the whole code:
Dim con As New SqlCeConnection(ConfigurationManager.ConnectionStrings("MyConnectionString").ToString)
Dim cm_sel As New SqlCeCommand("SELECT fID FROM Files WHERE fCatID=" & catID, con)
Try
con.Open()
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
If rdr.HasRows() Then
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
End If
Return "{'result':'ok'}"
Catch ex As Exception
Return "{'result':'error'}"
Finally
con.Close()
con.Dispose()
End Try
You could call directly reader.Read since will return false if there are no rows. Simply remove the if statement surrounding the while.
UPDATED CODE:
Dim rdr As SqlCeDataReader = cm_sel.ExecuteReader
While rdr.Read
Documents.DeleteDocument(rdr.Item("fID"))
End While
This works fine for the above problem.
Dim hasrows As Boolean
hasrows = False
While (rdr.Read())
hasrows = True
End While
If (hasrows) Then
--do something
else
--do something else
end if
If you assign hasrows function to any Boolean and try to use it, the reader can jump to second record. The above solution will avoid that scenario as well.

.NET Framework Data Provider for Oracle multiple open connection

I have the below mentioned code in a seperate class file for establishing connection and carry out DB transactions. I have an issue where multiple connections being opened which sometime exceed the connection pool. When I stepped through the code I found that there are codes which call ConnectDB() in a loop without calling DisconnectDB(). But I expected that the condition OraConn.State = ConnectionState.Closed should handle the situation. Somehow the condition is always satisfied hence openning another set of connection. Can you suggest where am I going wrong and also what best practice can be adopted here?
Public Class Connection
Dim Str_conn As String = "Data Source=...; User=...; password=...; Min Pool Size=10; Max Pool Size=500;"
Public OraConn As OracleConnection
Dim cmd As OracleCommand
Dim dr As OracleDataReader
Dim data_adapt As OracleDataAdapter
Dim dt As DataTable
Dim ds As DataSet
Public Sub ConnectDB()
OraConn = New OracleConnection(Str_conn)
If OraConn.State = ConnectionState.Closed Then
OraConn.Open()
End If
End Sub
Public Sub DisconnectDB()
If OraConn.State = ConnectionState.Open Then
OraConn.Close()
End If
End Sub
Public Function get_dataset(ByVal query As String, ByRef ds As DataSet) As DataSet
data_adapt = New OracleDataAdapter(query, OraConn)
data_adapt.Fill(ds)
Return ds
End Function
Public Function get_datareader(ByVal query As String) As OracleDataReader
cmd = New OracleCommand(query, OraConn)
dr = cmd.ExecuteReader()
Return dr
End Function
Public Sub UpdateDB(ByVal query As String)
cmd = New OracleCommand(query, OraConn)
cmd.ExecuteNonQuery()
cmd.Dispose()
End Sub
The class is refered in other classes or directly in the aspx.vb pages like this.
Public Function InsertData(ByVal var1 As String, ByVal var2 As String) As Integer
conn.ConnectDB()
Dim qryInsert As String
qryInsert = " INSERT INTO TABLE VALUES ('" & var1 & "', "
qryInsert = qryInsert & var2 & "')"
Try
conn.UpdateDB(qryInsert)
Catch ex As OracleException
If ex.Code = 1 Then
updData(var1, var2)
ElseIf ex.Code = 2091 Then
msgprompt("Duplicate Unique Key!", "Warning")
End If
Finally
conn.DisconnectDB()
End Try
Return count
End Function
The connection is again opened in function updData(). While I understand that it has to be closed correctly but keeping tab on every developer is not possible. Hence I want to control it directly from the connection class by using the same connection but the condition If OraConn.State = ConnectionState.Closed is not helping.
UPDATE
I have put the code in UpdateDB under a Using block and removed call to ConnectDB and DisconnectDB from function like InsertData(...). It seems that the issue has been resolved. But I would like to know in case of exception will the connection remain open? and also OraConn is a public variable defined outside Using block so will it be disposed of by the GC?
Public Sub UpdateDB(ByVal query As String)
Using OraConn = New OracleConnection(Str_conn)
cmd = New OracleCommand(query, OraConn)
Try
OraConn.Open()
cmd.ExecuteNonQuery()
Catch ex As Exception
Throw
Finally
cmd.Dispose()
End Try
End Using
End Sub
You must close all the connections as soon as you are done with it, no matter what.
Suggestion:
The best practice for closing the connection is to do it in finally block. So that even if there is any error, catch it (log it if required) in catch block, and then connection will get close in finally block.
UPDATE
You can put one private static counter in your Connection class. When ever ConnectDB() is called you increment this counter and decrement it in every DisconnectDB(). Now in ConnectDB() you check the value of counter, if it exceeds a minimum threshold you throw error, by doing this way; you can come to know idle connection present in your code and refactor it. On production keep this threshold value high or ignore it in code.

Resources