MS Access: Method to process SQL without using RecordSource - sql

I would like to be able to find the last record in a table easily for SQL INSERT INTO table statement. I was hoping there would be a MS Access object or function which could read a SQL statement without requerying the whole context just to find specific counts or records. As I have been programming the only code I know that reads SQL is a recordset, is there a dummy copy or source you could just read without repointing the record to another? Otherwise, I need a way to access the table in VBA and count all records with a method. If this is not code yet is should be, this would make it so easy to get around code dialects, other methods (unless you need to use form objects) if you know SQL.
I have tried several things, such as that cast a tbl variable but there would be a type mismatch.
This needs a last statement so I get the new record... I need to know how to get the last record in the table with a count.
CurrentDb.Execute "INSERT INTO FormsHelpTable ([ID], [HelpTitle], [Comment]) VALUES " & _
"(" & (lastRecTbl + 1) & ", '" & Me.Text53 & "', '" & Me.Comment & "')", dbFailOnError
Me.RecordSource = "SELECT * FROM FormsHelpTable"
Me.Requery

This worked to find the last record:
http://www.minnesotaithub.com/2013/08/count-records-vba-microsoft-access-2010/
Great code too.

Related

Increase Ms Access Insert Performance

I am using MS Access 2010, split in front end / back end; on a network drive (WAN) with 16+ table with one table of users (1.3 Million) which is mostly used for user information and is not insert heavy and few other tables, which will receive upto 2000+ inserts daily.
I have been able to optimize most of the read/select queries. Although 1 chunk of my code looks as below. This can be used for upto 2000 iterations daily.
Do Until rec.EOF
Dim vSomeId As Integer
vSomeId = rec!SomeId
'StrSQL = StrSQL & "INSERT INTO TransportationDetails ( TransportationId, SomeId)" & _
'"VALUES(" & vTransportationId & ", " & vSomeId & ");"
StrSQL = "INSERT INTO TransportationDetails ( TransportationId, SomeId)" & _
"VALUES(" & vTransportationId & ", " & vSomeId & ");"
DoCmd.SetWarnings False
DoCmd.RunSQL (StrSQL)
DoCmd.SetWarnings True
rec.Edit
rec!SomeBoolean = rec!SomeOtherBoolean
rec.Update
rec.MoveNext
Loop
My objective here, is to reduce the number of calls to the db to insert all the values. and MS ACCESS does NOT support having more than 1 query in a statement, as I tried in the commented part of the code. I also think the recordset upate method is a lot time consuming, and if any one can suggest a better way to update the recordset.
Is there any way I can trick Access to insert & Update in less hits to db through SQL Queries, or any other access feature. Or optimize in anyway, It can take up to 30 mins some time. Decreasing it to At least 2 - 5 mins will be appropriate.
P.S.
I can not switch to SQL Server, It is JUST NOT POSSIBLE. I am aware it can be done in way more optimal way through sql server and Access shouldn't be used for WAN, but I don't have that option.
Solution:
I went with Andre's and Jorge's solution. The time decreased by 17 times. Although Albert's Answer is correct too as I found my main issue was with the sql statements in a loop. Changing the edits in the recordset to sql didnt impact much on the time factor.
I should point out that in the case of inserting rows, you will find FAR better performance by using a recordset. A SQL “action” query will ONLY perform better if you operating on a set of data. The instant you are inserting rows, then you don’t have a “set” insert, and using a DAO recordset will result in MUCH better performance (a factor of 10 to 100 times better).
If you have now
S = "SELECT SomeId, SomeBoolean, SomeOtherBoolean " & _
"FROM recTable WHERE someCriteria"
Set rec = DB.OpenRecordset(S)
change your statements into
"INSERT INTO TransportationDetails (TransportationId, SomeId) " & _
"SELECT " & vTransportationId & ", SomeId " & _
"FROM recTable WHERE someCriteria"
and
"UPDATE recTable SET SomeBoolean = SomeOtherBoolean WHERE someCriteria"
For performance, avoid looping over Recordsets where possible. Use SQL statements that operate on whole sets instead.
I recently ran into a problem where I have to import 200,000 records into 12 Access tables every 6 hours. This took too long as I was inserting each record one at a time.
I picked up a tip from a colleague who suggested using Linked Tables.
So I set up a linked table in my Access Database which was linked to a semi-colon delimited text file.
My program then created that semi-colon delimited text file every 6 hours.
You then select from the linked table into the table needed and that table is created.
This made my process immensely faster and I would definitely suggest it as an option.

Why Excel VBA can't query tables with the # symbol?

I'm trying to query a table, call it history#integration.
When I query the table, with this type of query:
select * from history#integration where id=5
and get the expected output.
With excel I connect to the database in this way:
cn.Open ( _
"User ID=" & userID & _
";Password=" & password & _
";Data Source=" & datasource & _
";Provider=MSDAORA.1")
but I get a runtime error of data type is not supported. I've verified using the exact same connection I can query the database with other "standard" tables like select * from history. Any thought on how I can get the "correct" type.
In Oracle (assuming this is what you're using, and it would be helpful to state that in your question) # is typically used to represent a database link: likely it's not part of the table name, but the table "history" is actually in a different database linked to by a DB link named "integration".
Not all datatypes are selectable over an Oracle DB link (LOB types for example)
# is a reserved character in SQL. Try surrounding the table name with brackets like: [history#integration].

Visual Basic.Net Insert multiple rows into a table

I am a relative newbie and trying to insert multiple rows (and data from textboxes) from one table into another and am stuck.
This SQL identifies the data to be inserted into the table
strsql = "SELECT '" & textbox1.text & "', '" & Textbox2.text & "', "
strsql = strsql & " a.TaskNum, a.StartDay, a.NumofDays FROM VETTimeLines as a"
strsql = strsql & " ORDER BY a.StartDay"
I started out along the lines of -> Insert into StudentProgram Values() code shown above, after 3 days of trying I now look forward to your advice.
Many thanks in anticipation
Peter
Inserting data using C# can be performed in variety of ways such as using Entity Framework or using ADO.NET, as you have chosen to do in this case.
Using ADO.NET you either write the insert as you did or by using DataAdapter approach. DataAdapter is capable of creating the SQL code for you, amongst other things. For example see:SQL DataAdapter. It is a good idea to not build a SQL string as you did because of sql injection threat as #Joel Coehoorn indicates in his comment above.
One way to overcome this is by using Parameters as shown in the above link. If you decide to provide the SQL for insert yourself with parameters, here is a good example:StackOverFlow-Insert using ADO.
The idea behind all of the above code is to create a connection object, create a parameter object, create a command object, open the database connection, execute the command and close the connection.
Try one of the above approaches and let's know your specific issue if any arises.

Append query with no From clause

I have a MS Access database that records financial transactions. It has a form named frmDeposits that is based on table tblDep. One of the buttons on that form runs a procedure that inserts data from the current record into another table, tblAccount, using DoCmd.RunSql. The code looks like this:
DoCmd.RunSQL "INSERT INTO tblAccount ([Date], CheckNo, Amount, Vendor, Cleared, Deposit, Printed, Misc) " _
& "SELECT [Date], CheckNo, Amount, Vendor, Cleared, " & ident & " AS Deposit, Printed, Misc " & _
& "FROM tblDep WHERE Form=" & formnum & ";"
The formnum variable is set elsewhere, and identifies the current record in the form. The ident variable is also defined elsewhere.
Somehow, in the process of debugging other parts of my code, the last line of this SQL statement was erased, leaving:
DoCmd.RunSQL "INSERT INTO tblAccount ([Date], CheckNo, Amount, Vendor, Cleared, Deposit, Printed, Misc) " _
& "SELECT [Date], CheckNo, Amount, Vendor, Cleared, " & ident & " AS Deposit, Printed, Misc"
Surprisingly, the form continued to operate correctly! This RunSQL statement was still picking up the current record from frmDeposits and inserting it into the tblAccount table.
My question is, why does this work? I thought that SQL statements with a SELECT had to have a FROM clause. I know you can use INSERT INTO ... VALUES with no FROM to insert a single record, but even then you have to supply actual values and not field names.
One other thing I noticed: This only seems to work on code in the form's module. If I paste the SQL string into a query design and run it, or run similar code outside the form's scope, I get the 'Enter Parameter Value' popup box for each field. Is VBA pre-parsing the SQL string, and grabbing the form fields or text boxes for the parameters? Or is it defaulting the FROM to the form's RecordSource? I don't have text boxes on the form for all the fields referenced in the SQL string, although they all exist in the form's underlying table.
Btw, this is running in Access 2000. Yes, I know it's an outdated version, but that's what I have to work with.
**Edit -
One added note, this behavior only shows up when using DoCmd.RunSQL. If I put the same SQL string into a db.Execute, it returns an 'Wrong number of parameters' error.
VBA code exists in two forms in an Access application: plain text source; and compiled "p-code". Perhaps what has happened is the stored p-code didn't get changed when that part of the source code text went missing. IOW, it still includes symbols for the missing FROM clause.
In your situation, I would suspect corruption and perform a decompile to clean up the compiled code. First make a backup of the database for safe keeping. You can find detailed instructions for decompile in the 2 answers to this question: HOW TO decompile and recompile.
Frankly corruption is sort of a wild guess. However, since part of your source code mysteriously disappeared and Access operates as if it's still there, corruption seems like a stronger possibility.
Another possibility is you have DoCmd.SetWarnings = False. Turning SetWarnings off silently discards the error message about the failed INSERT attempt. So you don't see an error message but nothing actually gets inserted, either.

Run Query Against ODBC Connected Table VBA

I have a table (readings) already connected by ODBC in Access that opens very quickly when I click on it.
However, when I try to run this in VBA I it locks up and never displays anything:
Dim strSql As String
strSql = "SELECT readings.ids " & _
"INTO ids_temp " & _
"FROM readings " & _
"WHERE readings.ids > 1234;" //This is id in middle of list
DoCmd.SetWarnings False
DoCmd.RunSQL strSql
DoCmd.SetWarnings True
For some reason this crashes the whole system. Any ideas?
Rather than using DoCmd, t's usually handled by your existing connection to create a Command object, which accepts SQL statements to use with the Command.Execute method.
Reading the documentation for DoCmd, it appears to primarily be intended for eexecuting Macros from the Access UI menus.
Does you Database have ids_temp table locally? If ids_temp table is Linked table it will delete the table, because select into CREATES NEW TABLE. If you want to add to table try INSERT INTO command. You can clean table before inserting the data.
So the error was actually my fault the id I was using was causing the Query to return about 6 million results. But, this method actually works great, I just create the table and link a list box on a different form to the table, then I just show the form. I do some closes and updates in between but overall it seems to work well. Thanks for the help
Let me say that DoCmd.RunSQL is never advisable, particularly with SetWarnings turned OFF, as you have no idea whether the result is what you expect or not. You've told VBA not to report errors, so you never know if all the records were inserted or not.
It's very easy to replace DoCmd.RunSQL with my SQLRun() function, posted here:
How can I get a value from the update query prompt in Access VBA?