I use QTP/UFT for my application testing.
I had to access my oracle DB (11g) to do some DB setup (to update records).
I use oracle.manageddataaccess.dll (referenced to myDBWrapper class library project).
I have below dlls
(myDBWrapper is the one I created - where the issue is present)
My connection string:
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=<HOST>)(PORT=<PORT>>)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=<SERVICENAME>)));User Id=<USERNAME>;Password=<PASSWORD>;
Issue:
The below code during conn.open() throws error. It works sometimes & sometimes throws an error that 'Object reference not to set an instance of an object' in the same machine.
conn = New OracleConnection()
conn.ConnectionString = ConnectionString
MsgBox("isnothing? : " & (conn Is Nothing).ToString) 'it is always False. So , not null
conn.Open() ' It throws an error that "Object reference not to set an instance of an object"
Dim cmd As OracleCommand = New OracleCommand(strQuery)
cmd.BindByName = True
cmd.Connection = conn
RowsAffected = cmd.ExecuteNonQuery()
cmd.Dispose()
conn.Dispose()
Note:
It is not a resource leak. I just make 1 connection and dispose. No one else is connecting to the DB.
Issue happens - When QTP has COM lib. When i use that to automate & make it invisible (QTP.Visible = FALSE). If I use QTP.Visible = TRUE - issue does not happen. What kind of issue is this!!!
StackTrace :
Object reference not set to an instance of an object.
at OracleInternal.I18N.Conv.GetMaxBytesPerChar(Int32 charsetId)
at OracleInternal.ServiceObjects.OracleConnectionImpl.Connect(ConnectionString cs, Boolean bOpenEndUserSession)
at OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd)
at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd)
at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword)
at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword)
at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
at myDBWrapper.Utility.DBUtil.OpenConnection()
Because that looks like VB.NET Have you got that code in a form load? That event is unpredictable if you are not showing the form.
have u tried the oracle connection using the ADOB connection object ? you need to have the Oracle driver installed and it will help you to connect to the DB by creation the ADOB connection object
Try this
conn = New Oracle.ManagedDataAccess.Client.OracleConnection(ConnectionString)
Related
I have this code in Visual Basic, every time I have a new insert:
Private _conn As SqlConnection
Public Function Include(ByVal pSql As String, Optional timeout As Integer = 120) As Boolean
Try
Dim SQL_Str = "my string of conection... with database. not put on this example"
_conn = New SqlConnection(SQL_Str)
_conn.Open()
_adapter = New SqlDataAdapter
cmd.CommandTimeout = timeout
cmd.Connection = _conn
cmd.CommandText = pSql
cmd.CommandType = CommandType.Text
_adapter.InsertCommand = cmd
_adapter.InsertCommand.ExecuteNonQuery()
Catch ex As Exception
InputBox("New Error on Sql cmd: ", , pSql)
End Try
_conn.Close()
_conn.Dispose()
_conn = Nothing
_adapter.Dispose()
_adapter = Nothing
End Function
Ok this is a straightforward way to update the database.
But supose I have 1000 connections at the same time, do the application would support this kind of approach?
Do this method support simultaneous threads acessing the _conn object?
Is it really necessary to create a pool of connections to handle data?
Do a pool of connections will really improve something?
E.g. with this I'm overloading the application instead of the database?
If so, how would I do it on VbNet/Visual Basic?
Yes, pooled connections really are faster. They keep you from needing to continually re-negotiate login and protocol information. Even better, this is already built into the SqlConnection type, and it's done in a reasonably thread-safe way (where the existing code is not).
The short version is you really do want to create a brand new connection object for most queries, and you do not want to try to share the same connection variable throughout an application or session.
Given that, I see several big problems in that code:
Treating a class-level _conn variable as if it were local, making it impossible to share instances of this class safely across threads.
No mechanism to clean up the connection if an exception is thrown (needs a Finally or Using block. Just closing after the Catch isn't good enough.
No way to pass separate query parameters in the function signature. This will force you to write horribly insecure code elsewhere that's crazy-vulnerable to sql injection attacks. It's the kind of thing where you wake up one morning to find out you were hacked over a year ago, and IMO borders on professional malpractice.
Mixing UI code with utility code.
You want something more like this:
Private cnString As String = "my string of conection... with database. not put on this example"
Public Sub Include(pSql As String, parameters() As SqlParamter, Optional timeout As Integer = 120)
Using conn As New SqlConnectioN(cnString), _
cmd As New SqlCommand(pSql, conn)
If parameters IsNot Nothing AndAlso parameters.Length > 0 Then
cmd.Parameters.AddRange(parameters)
End If
conn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
And you might call it like this (assuming type or instance name is DB):
Dim pSql As String = "INSERT INTO [ExampleTable] (FirstName, LastName, CreationDate) VALUES (#FirstName, #LastName, #CreationDate)"
Dim parameters = {
New SqlParameter("#FirstName", SqlDbType.NVarChar, 20),
New SqlParameter("#LastName", SqlDbType.NVarChar, 20),
New SqlParameter("#CreationDate", SqlDbType.DateTime)
}
parameters(0).Value = "John"
parameters(1).Value = "Smith"
parameters(2).Value = DateTime.Now
Try
DB.Include(pSql, parameters)
Catch ex As Exception
MessageBox.Show(String.Format("New Error on Sql cmd:{0}{1}{0}{0}Message:{2}",vbCrLf, pSql, ex.Message)
End Try
I'm using simple DataReader commands very often in my project.
To simplify it, I've created a function:
Public Function DataReaderFromCommand(ByRef uCn As SQLite.SQLiteConnection, ByVal uCommandText As String) As SQLite.SQLiteDataReader
Dim nCmdSel As SQLite.SQLiteCommand = uCn.CreateCommand
With nCmdSel
.CommandText = uCommandText
End With
Dim r As SQLite.SQLiteDataReader = nCmdSel.ExecuteReader
Return r
End Function
In my project I use it like this:
Using r As SQLite.SQLiteDataReader = DataReaderFromCommand(cnUser, "SELECT * FROM settings")
Do While r.Read
'do something
Loop
End Using'this should close the DataReader
In one case, I need to delete my database. However this fails with the error "File is locked by another process".
I tried to isolate the problem, and the locking occurs because of the function "DataReaderFromCommand".
Does anybody see what I'm doing wrong / what keeps the database locked?
I thought that after "End Using" of the datareader, the SQLiteCommand would also be disposed, so there are no further reference to the database.
You should probably be trying to do it this way:
Public Sub UsingDataReader(ByVal connectionString As String, ByVal commandText As String, ByVal action As Action(Of SQLite.SQLiteDataReader))
Using connection As New SQLite.SQLiteConnection(connectionString)
Using command As New SQLite.SQLiteCommand(commandText, connection)
Using reader = command.ExecuteReader()
action(reader)
End Using
End Using
End Using
End Sub
Then you can call the code like this:
UsingDataReader("/* your connection string here */", "SELECT * FROM settings", _
Sub (r)
Do While r.Read
'do something
Loop
End Sub)
This ensures that all of the disposable references are closed when the Sub has completed.
The first problem is that not all the disposables are being disposed of. We are assured that the connection passed to that helper is in a Using block, but the command also needs to be disposed of as it has a reference to the connection:
Dim cmd As New SQLiteCommand(sql, dbcon)
Even if you dont use the overloaded constructor, in order to work, somewhere you set the connection property. This illustrates one of the problems with such "DB helper" methods: the DBConnection, DBCommand and DBReader objects work together very closely, but they are created in different methods with different scopes and you can't normally see if everything is being cleaned up properly.
The code posted will always fail because that DBCommand object - and by extension the DBConnection - are not disposed. But even if you clean up properly, pooling will keep the DBConnection alive for a while as jmcilhinney explains. Here are 2 fixes:
Clear the Pool
Using dbcon As New SQLiteConnection(LiteConnStr),
cmd As New SQLiteCommand(sql, dbcon)
dbcon.Open()
Dim n As Int32 = 0
Using rdr = cmd.ExecuteReader
While rdr.Read
' == DoSomething()
Console.WriteLine("{0} == {1}", n, rdr.GetString(0))
n += 1
End While
End Using
' Clears the connection pool associated with the connection.
' Any other active connections using the same database file will be
' discarded instead of returned to the pool when they are closed.
SQLiteConnection.ClearPool(dbcon)
End Using
File.Delete(sqlFile)
The dbCon and cmd objects are "stacked" into one Using statement to reduce indentation.
This will close and discard any and all connections in the pool, provided they have been Disposed - as well as any objects which reference them. If you use Dim cmd ... you will need to explicitly dispose of it.
Force Garbage Collection
I think this is much more ham-fisted, but it is included for completeness.
Using dbcon As New SQLiteConnection(LiteConnStr),
cmd As New SQLiteCommand(sql, dbcon)
...
Using rdr = cmd.ExecuteReader
...
End Using
End Using
GC.WaitForPendingFinalizers()
File.Delete(sqlFile)
This also works as long as everything has been properly disposed of. I prefer not to mess with GC unless absolutely necessary. The issue here is that clean up will not be limited to DBProvider objects but anything which has been disposed and is awaiting GC.
Yet a third workaround would be to turn off pooling, but you would still have to dispose of everything.
You are going to need to also close your cnUser connection to the database.
Closing/disposing the reader does not necessarily close/dispose the open connection.
I'm having a problem in project of mine in VB.NET. The problem is whenever I want to save, delete or update data with an Access database I get an error with a message saying that "not allowed to change the connection string property. connection's current state is open".
I have used If con.State = ConnectionState.Open Then con.Close() End If
command using finally in every section where I have called the database.
But still I'm having the same problem. What am I doing wrong?
Use the "USING"-Keyword. Exiting a using block calls .Dispose() on the object which for a SqlConnection will close the connection and any open resources.
Using connection As New SqlConnection(connection)
Dim command As New SqlCommand("Select * From dbo.table1",connection)
command.ExecuteNonQuery()
End Using
EDIT:
Module Module1
Public Sub DbConnection()
Dim connectionString as String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=yourServerAddress;Initial Catalog=university.mdb;
Integrated Security=SSPI;"
Using connection as New Sqlconnection(connectionstring)
Dim command As New SqlCommand("Select * From dbo.table1",connection)
command.ExecuteNonQuery()
End Using
End Sub
End Module
I'm working on test code to connect to PostgreSQL using npgsql library this is code sample:
Dim conn As Npgsql.NpgsqlConnection = New Npgsql.NpgsqlConnection("Server=localhost;Database=Fox;User Id=postgres;")
conn.Open()
Dim cmd As Npgsql.NpgsqlCommand
cmd = New Npgsql.NpgsqlCommand("select userName from users where id = 1")
'etc
when running my code an exception is raised (in line conn.open() ):
An unhandled exception of type 'System.ArgumentNullException' occurred in Npgsql.dll
Additional information: String reference not set to an instance of a String.
Where is the problem?
I´m experimenting troubles on a local connection to SQL Server 2008, it´s throwing me the next especific error:
A network-related or instance-specific error ocurred while establishing a connection to SQL Server. The server was not found or was not accesible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections (error 40)
I´ve tried with most of solutions concerning to SQL Services and Firewall Solutions, so i think the problem is specific in the source code, so it is:
Private Sub cargar_Combo(ByVal ComboBox As ComboBox, ByVal sql As String)
Dim strConexion As String = "Data Source=Angel-PC\SQLEXPRESS1;Initial Catalog=sistemaReferencias;Integrated Security=True"
Dim conexion As New SqlConnection(strConexion)
Try
conexion.Open()
Dim cmd As New SqlCommand(sql, conexion)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
da.Fill(ds)
ComboBox.DataSource = ds.Tables(0)
ComboBox.DisplayMember = ds.Tables(0).Columns(1).Caption.ToString
ComboBox.ValueMember = ds.Tables(0).Columns(0).Caption
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
If conexion.State = ConnectionState.Open Then
conexion.Close()
End If
End Try
End Sub
I know that the String connection is right, because i used it in another method, the error comes specifically at the "da.Fill(ds)" line, those are the basics
I really appreciate any help you can provide.
Go to your desktop. Right click and add a new text file, "test.txt".
Rename the text file to test.udl, you will get a warning, just accept it.
Double click test.udl, and you will have an interactive dialog to configure your connection string.
Once you have configured the connection string. Click save. The right click the test.udl file and open in notepad. This will give you the connection string that you need to put into your app.