Oracle database query throws error on second run - oracle

i have an VBA code where i am calling oracle to retrieve data twice using ODBC.
First data retrieval is fine. But 2nd time it is saying ,
**RunTime Error '-2147467259 (80004005)'; Unspecified error**
My Code is as follows,
Note: Same code works for connecting Teradata but failed when i use
Oracle
'First Data retrieval
Query1 = "Select TableName from all_tables"
CmdSQLData.CommandText = Query1
CmdSQLData.CommandType = adcmdText
CmdSQLData.Timeout=0
set rs = CmdSQLData.Execute()
'Then code to store data ...
'This part gives proper result ...
rs.close()
'Second Data retrieval
Query2 = "Select * from db.Event"
CmdSQLData.CommandText = Query2
CmdSQLData.CommandType = adcmdText
CmdSQLData.Timeout=0
set rs = CmdSQLData.Execute() 'This line Gives Error - RunTime Error '-2147467259 (80004005)'; Unspecified error
Also i tried creating new command object as cmdSQLData1 but still same
error
May i know why the error is coming for second query ?
There is no problem with query as i have tested in oracle directory.
Please let me know

You won't see this documented much of anywhere, but reusing Command objects with different comamndText is actually a bad practice. You don't say what kind of connection you're using, but for example if it's ODBC, this will internally send a fake invalid SQL to Oracle to force a cleanup of some kind. So instead, throw away your Command object after use and create a new one.
Reusing Command objects is a good practice when you're re-executing the same query with different parameter values, but that's not the case here.

You do not need to use command text at all for those types of queries what you could do is :-
` Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
con.Open "DSN=Oracle", "User", "Password"
rs.Open "select * from table_a", con
' Read all results
rs.Close
rs.Open "select * from table_b", con
' Read all results
rs.Close
con.Close
You only need to use "Command" if you plan to use a store procedure or a query with bound parameters.

Related

Format dates using Windows form in Visual Studio

I am trying to update the database with the following query, but I am having difficulty formatting dates. What should I do?
string query = "update employee_info set FirstName ='txtfirstName.Text',LastName ='txtlastName.Text' ,Address1='txt_address', City = 'combo_city' ,Country='combo_Country',ReportsTo='txt_reportTo' WHERE Bday='dtp_birthDate.Value.ToShortDateString()' and HireDate='dtp_hireDate.Value.ToShortDateString()'";
You should use a parameterized query instead. This gets you around having to format the strings for the where clause correctly and also prevents you from being vulnerable to SQL injection attacks (https://en.wikipedia.org/wiki/SQL_injection)
Something like this (the below sample has a shortened version of your query and lacks setting up a db connection).
strQuery = "update employee_info set FirstName=#firstName, LastName=#lastName WHERE Bday=#birthDate and HireDate=#hireDate";
cmd = new SqlCommand(strQuery);
cmd.Parameters.AddWithValue("#firstName", txtfirstName.Text);
cmd.Parameters.AddWithValue("#CompanyName", txtLastName.Text);
cmd.Parameters.AddWithValue("#birthDate", dtp_birthDate.Value);
cmd.Parameters.AddWithValue("#hireDate", dtp_hireDate.Value);
cmd.ExecuteNonQuery();

Dataset is empty

I have a problem, I'm working on a school project with Visual Basic and I can't manage to fill a dataset with a LIKE query.
I'm using Access in order to manage the database and the query is:
SELECT * FROM VistaProductos WHERE Nombre LIKE "*ta*"
In Access this query is working fine but when I use it on Visual Basic the OleDbDataAdapter fills my DataSet with 0 rows.
Here is the code:
Dim adaptador As New OleDbDataAdapter("SELECT * FROM VistaProductos WHERE " & campo & " LIKE ""*" & valor & "*""", conexion)
adaptador.Fill(dataset, tabla)
Return dataset
campo and valor are variables who have the same data as in the Access example, and I tried by writing them literally too.
The connection to the database is working fine as the other querys work perfectly.
ADO.NET uses the standard % character as wildcard in LIKE expressions.
But your first problem to solve is removing the string concatenations when you build sql queries. You cannot trust your user on this point. If you leave in that way you user can write anything and you risk to pass malicious commands to your database engine. You should always use parameters in these contexts
In your code is present also a field name as a variable part of the query.
This cannot be parameterized, so the only sensible solution is to present your user with a list of field names to choose from
Dim cmdText = "SELECT * FROM VistaProductos WHERE " & campo & " LIKE #valor"
Dim adaptador As New OleDbDataAdapter(cmdText, conexion)
adaptador.SelectCommand.Parameters.Add("#valor", OleDbType.VarWChar).Value = "%" & valor & "%"
adaptador.Fill(dataset, tabla)
Return dataset

Update Does Not Work in VS2010 Using IDB2

I have no problem when trying to execute and insert or a delete SQL Command. However, this update command does not seems to work well and I am having a hard time to figure it out. Kindly help me please.
I am using an i Series or AS/400 database.
Imports IBM.Data.DB2
Imports IBM.Data.DB2.iSeries
Public conn As New iDB2Connection
Public str As String = "Datasource=10.0.1.11;UserID=edith;password=edith;DefaultCollection=impexplib"
Dim cmdUpdate As New iDB2Command
Dim sqlUpdate As String
conn = New iDB2Connection(str)
conn.Open()
sqlUpdate = "UPDATE impexplib.expusers SET loginDate=#loginDate, loginTime=#loginTime WHERE username=#username"
cmdUpdate.Parameters.Add("username", iDB2DbType.iDB2VarChar)
cmdUpdate.Parameters.Add("loginDate", iDB2DbType.iDB2Date)
cmdUpdate.Parameters.Add("loginTime", iDB2DbType.iDB2Time)
cmdUpdate.Parameters("username").Value = txtUsername.Text
cmdUpdate.Parameters("loginDate").Value = Now.ToString("d")
cmdUpdate.Parameters("loginTime").Value = Now.ToString("T")
cmdUpdate.Connection = conn
cmdUpdate.CommandText = sqlUpdate
cmdUpdate.ExecuteNonQuery()
conn.Close()
Please help me what I am doing wrong? The update code does not really work. Even a simple update of password does not work to.
Thanks!
Assuming no error messages anywhere, if no update is occurring, then the WHERE clause is not being satisfied. Make sure that the user name in DB2 exactly matches the parameter used in the WHERE clause. Very often, DB2 columns are CHAR, not VARCHAR or the other way round. You may also have a situation where the DB2 column is all upper case and the parameter is mixed case. Imagine the DB2 column has "FRED BLOGGS " and your parameter has "Fred Bloggs". This won't satisfy the WHERE clause and no rows will be updated.

very slow record inserts into Jet database using ADO.NET / OleDb

I'm trying to insert a lot of records into a Jet (Access) database via ADO.NET / OleDb. It is running painfully slowly. The slowness is mainly due to the DbDataAdapter.Update method. In Microsoft's words,
...these statements are not performed as a batch process; each row is updated individually.
This is a real WTF as my database application gives about 30 times slower performance than the equivalent code in VB6 using old ADO or DAO (a Recordset with an AddNew / Update loop).
The SqlClient provider has the SqlBulkCopy class; is there anything equivalent for OleDb?
Even being able to change its write-caching behaviour might help. (ie. don't flush the cache after each row is inserted!)
Is there anything I can do, or is ADO.NET just broken for Jet?
*Edited to add: Here's a cut down version of my code, using a cut down test database.
First, the VBA/ADO version (Access 2003):
Dim con As ADODB.Connection
Set con = CurrentProject.Connection
con.Execute "DELETE * FROM tblTest", , adCmdText Or adExecuteNoRecords
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open "tblTest", con, , adLockPessimistic
Dim i&, t!
t = Timer
For i = 1 To 10000
rs.AddNew
rs!mainKey = i
rs!testColumn = Rnd * 100
rs.Update
Next
rs.Close
Debug.Print "time to add 10000 (by ADO) " & Timer - t
Output: time to add 10000 (by ADO) 0.296875
Now the ADO.NET version (VB.NET 2010):
Dim sProvider As String = "PROVIDER = Microsoft.Jet.OLEDB.4.0;"
Dim sDataSource As String = "Data Source = 'C:\test.mdb'"
Dim connection As New OleDbConnection(sProvider & sDataSource)
connection.Open()
Dim q As New OleDbCommand("DELETE * FROM tblTest", connection)
q.ExecuteNonQuery()
Dim ds As New DataSet
Dim selectCmd As OleDbCommand = connection.CreateCommand()
selectCmd.CommandText = "SELECT * FROM tblTest"
Dim da As New OleDbDataAdapter(selectCmd)
da.Fill(ds, "tblTest")
Dim theTable As DataTable = ds.Tables("tblTest")
For i As Integer = 1 To 10000
Dim row = theTable.NewRow()
row.Item("mainKey") = i
row.Item("testColumn") = Rnd() * 100
theTable.Rows.Add(row)
Next i
Dim t! : t = Microsoft.VisualBasic.Timer
Dim cb As New OleDbCommandBuilder(da)
da.Update(ds, "tblTest")
Debug.Print("time to add 10000 (by ADO.NET): " & Microsoft.VisualBasic.Timer - t)
connection.Close()
Output: time to add 10000 (by ADO.NET): 5.859375
Make sure that the connection is open when the method is called. If the connection is closed before the update method is called (I actually saw that in some example code) the update method may attempt to open the connection in a non-optimal way.
Opening connections in Jet can be very slow if the connection is not pooled. You may need to add OLE DB SERVICES = -1 to make sure the connection is pooled.
Slow MSAccess disk writing
Are you really trying to populate a table with random values? If so, there are faster ways to do it (using an INSERT based on an existing table, or on the table you're appending to, so you can run it multiple times and quickly reach the number of desired records).
In general, a SQL INSERT is going to be an order of magnitude faster than adding one record at a time. If you have to do it the way you're doing it, then you might look into whether or not you can use a Jet/ACE transaction via ADO/ADO.NET. I haven't a clue whether that's available or not. If it's not, and assuming COM is an option, you should consider just using DAO so you could use Jet/ACE transactions, which will delay the write to the very end (like posting a batch).
I'm no ADO maven, but I recally there being some batch functions in Classic ADO, too, so you might consider investigating that, as well.

Cannot executing a SQL query through ODP.NET - invalid character error

I'm trying to execute a SQL query through ODP.NET to create a table, but I always get an ORA-00911 'invalid character' error. The Errors object in the exception always has the text "ORA-00911: invalid character\n", even if there are no linebreaks in the SQL query itself.
The code I'm executing the SQL is this:
using (OracleConnection conn = new OracleConnection(<connection string>) {
using (OracleCommand command = conn.CreateCommand()) {
conn.Open();
command.CommandText = queryString;
command.ExecuteNonQuery(); // exception always gets thrown here
}
queryString contains a single CREATE TABLE statement, which works fine when executed through SQL Developer
EDIT: the SQL I am executing is this:
CREATE TABLE "TESTSYNC"."NEWTABLE" (
"COL1" NUMBER(*,0) NULL,
"COL2" NUMBER(*,0) NULL
);
with linebreaks removed
Other people have come across this issue - ODP.NET does not support multiple SQL statements in a text command. The solution is to wrap it in a PL/SQL block with EXECUTE IMMEDIATE around each statement. This lack of support for ; seems incredibly boneheaded to me, and has not improved my opinion of the oracle development team.
Furthermore, this seems to be an issue with oracle itself, as I have the same problems with the MS and ODBC oracle clients.
I had this issue for some reason you have to have code on one line.
I had strSQL = "stuff" +
" more stuff"
I had to put it on one line.
strSQL = "stuff more stuff"
It some how reads the cr/lf.
Wrap your sql in a Begin block.
Dim sqlInsert As String = ""
For i = 1 To 10
sqlInsert += "INSERT INTO MY_TABLE (COUNT) VALUES (" & i & "); "
Next
Call ExecuteSql("BEGIN " & sqlInsert & " END;")
Your quotes are OK (it just forces Oracle to treat your object names as case sensitive i.e. upper case the way you've written it) but I'm not at all sure you're allowed to define NUMBER that way with a *.
I wonder if it is the "*" in the sql have you tried the call without an * in the create? I bet it is yet another "feature" of the ODP.Net driver

Resources