I have a decent amount of experience with SAS and Access, and I know how to call Access from VBA, but I am having a problem with table locks that I need help with.
Essentially what I am doing is running a proc freq in SAS, passing it to a table in Access so it can be read in a subform.
I have a form with some combo boxes where the user can select info about what variable they want the frequency of. Then they click a button and VBA passes those parameters on to SAS, and the subform populates with frequency data from SAS.
Everything works except the final part.
I have successfully taken the parameters from Access, passed them to SAS, and run the correct frequency. But during SAS's proc export back to Access, I get an error stating: "Exectute: The database engine could not lock table "FREQ" because it is already in use by another person or process."
The issue is that the table that SAS is exporting to is used in Access by the form that opens SAS.
Since I am obviously not using the form while SAS is processing, is there a way to have the form unlock or disconnect from the table so that SAS can access it, and then reconnect the table to the form after SAS finishes processing?
I tried splitting the database, but I got the same problem.
The problem maybe was caused by the fact that the SAS was connecting with the ACCESS. First clear the connection(such as: libname libname_name clear), and then connect with Access.
Related
I have inherited a MS Access DB (2007) which I am converting into a MySQL database. I have exported all the custom queries with no issues. But I cannot find the form INSERT query.
The DB has a form which contains sub-forms. There is one submit button which onclick validates the form and then calls acCmdSaveRecord which presumably inserts the record into the database.
Because the database schema is a moderately complex RDB I want to be able to view or export the INSERT query Access runs when saving a record so I can convert it to MySQL.
Is this possible and if so how would I do it?
You can't. That is done by Access behind the scene when using a bound form.
If you link the table from MySQL and bind your (sub)forms to the updated tables and views, the forms will still read and write your data.
I have this problem: I'm using a SQL Server 2008R2 backend and MS Access 2000 frontend where some tables are connected via ODBC.
Following Structure (Tables all on SQL-Server):
Import (not connected to Access)
Products (connected via ODBC to Access)
Pricing (connected via ODBC to Access)
I want to fill the Pricing table automatically with some data from Products and Import. This is supposed to run as a SQL Agent job with a T-SQL script.
I want to insert the data from "Products" with following command:
INSERT INTO Pricing (Productnr, Manufacturernr)
(SELECT Productnr, Manufacturernr
FROM Products
WHERE Valid = 1
AND Productnr NOT IN (SELECT Productnr FROM Pricing ));
Right after that the inserted rows are locked for Access, I can't change anything. If I execute sql queries with SQL Server Management Suite or if i start queries as SQL Agent jobs everything works fine.
Why are the rows locked in ms access after the query ran (even if it finished successfully)? and how can I unlock them or make it unlock itself right after the query/job ran?
Thanks
When SQL Server inserts new rows, those new rows are in fact exclusively locked to prevent other transactions from reading or manipulating them - that's by design, and it's a good thing! And it's something you cannot change - you cannot insert without those locks.
You can unlock them by committing the transaction that they're being inserted under - once they're committed to SQL Server, you can access them again normally.
The error message i get says, that the dataset has been changed by another user and if i save it, i would undo the changes of the other user. (and asks me for copying into clipboard).
This is different from "locked", and completely normal.
If you have a ODBC linked table (or form based on the table) open, and change data in the backend, Access doesn't know about the change.
You need to do a full requery (Shift+F9) in Access to reload the data, afterwards all records can be edited again.
Got the solution for my Problem now.
I had to add a timestamp row into the pricing table, so access could recognize the change.
Access loads the data into the front end when the table is first accessed. If something in the backend changes the data, you need Access to refresh it first, before you can edit it from the front end (or see the changes).
Do this by (in Access) by closing and reopening the table, or switching to the table and pressing shift-F9 as Andre suggested, or programmatically using a requery statement. You must requery, not refresh, for it to release the locks and register the changes made in SQL.
I have 2 table, one is local named 'Client' and other is a linked table to MySQL DB in my web-server named 'ClientSql'.
When I insert data into the table Client, I want it to be insert into clientSql too. I try it with data macro (after insert), but it shows me an error saying
It's not possible in linked tables.
I have tried to create an append query successfully, and it works, but it just works if I execute it manually. My question is:
Is it possible to call it from a data macro? if is possible, can you show me how? If not, can you point me to a solution?
I'm not sure why you should be able to do it manually, but not via a macro. According to this link
http://dev.mysql.com/doc/connector-odbc/en/connector-odbc-examples-tools-with-access-linked-tables.html
you should be able to do it either way.
Another thought is to eliminate the local access client table and have the access program update the mySql table directly. However, if another program is accessing the client table at the same time, this could become tricky due to multi-user and locking situations.
I'm migrating the data from an Access database to SQL Server via the SQL Server Migration Assistant (SSMA). The Access application will continue to be used with the local tables converted to linked tables.
One continuous form hangs for 15 - 30 seconds when it's loading. It displays approximately 2000 records. When I looked in SQL Server Profiler to see what it was doing, it was making a separate call to the backend database for each record in the form. So the delay when the form opens is caused by the 2000-odd separate calls to the database.
This is amazingly inefficient. Is there any way to get Access to make a single call to the backend database and retrieve all the records at once?
I don't know if this is relevant but the Record Source for the form is a view in the SQL Server backend database, which is linked to via an Access linked table (so, hopefully, Access just sees it as a table, not a view). I needed an Instead Of trigger on the view in SQL Server, and a unique index on the linked table in Access, to allow the records to be updated via the form.
If the act of opening that continuous form really does generate ~2000 separate SQL queries (one for every row in the view) then that is unusual behaviour for Access interacting with a SQL Server linked "table". Under normal circumstances what takes place is:
Access submits a single query to return all of the Primary Key values for all rows in the table/view. This query may be filtered and/or sorted by other columns based on the Filter and Order By properties of the form. This gives Access a list of the key values for every row that might be displayed in the form, in the order in which they will appear.
Access then creates a SQL prepared statement using sp_prepexec to retrieve entire rows from the table/view ten (10) rows at a time. The first call looks something like this...
declare #p1 int
set #p1=4
exec sp_prepexec #p1 output,N'#P1 int,#P2 int,#P3 int,#P4 int,#P5 int,#P6 int,#P7 int,#P8 int,#P9 int,#P10 int',N'SELECT "ID","AgentName" FROM "dbo"."myTbl" WHERE "ID" = #P1 OR "ID" = #P2 OR "ID" = #P3 OR "ID" = #P4 OR "ID" = #P5 OR "ID" = #P6 OR "ID" = #P7 OR "ID" = #P8 OR "ID" = #P9 OR "ID" = #P10',358,359,360,361,362,363,364,365,366,367
select #p1
...and each subsequent call uses sp_execute, something like this
exec sp_execute 4,368,369,370,371,372,373,374,375,376,377
Access repeats those calls until it has retrieved enough rows to fill the current page of continuous forms. It then displays those forms immediately.
Once the forms have been displayed, Access will "pre-fetch" a couple of more batches of rows (10 rows each) in anticipation of the user hitting PgDn or starting to scroll down.
If the user clicks the "Last Record" button in the record navigator, Access again uses sp_prepexec and sp_execute to request enough 10-row batches to fill the last page of the form, and possibly pre-fetch another couple of batches in case the user decides to hit PgUp or start scrolling up.
So in your case if Access really is causing SQL Server to run individual queries for every single row in the view then there may be something particular about your SQL View that is causing it. You could test that by creating an Access linked table to a single SQL Table or a simple one-table SQL View, then use SQL Server Profiler to check if opening that linked table causes the same behaviour.
Turned out the problem was two aggregate fields. One field's Control Source was =Count(ID) and the other field's Control Source was =Sum(Total_Qty).
Clearing the control sources of those two fields allowed the form to open quickly. SQL Server Profiler shows it calling sp_execute, as Gord Thompson described, to retrieve seven batches of 10 rows at a time. Much quicker than making 2000 calls to retrieve one row at a time.
I've come across the same problem again but this time with a different cause. I'm including it here for completeness, to help anyone in a similar situation:
This time the underlying query was hanging and SQL Server Profiler showed the same behaviour as before, with Access making separate calls to the SQL Server database to bring back one record at a time, for every record in the query.
The cause turned out to be the ORDER BY clause in the query. I guess Access had to pull back all records in the linked table from SQL Server before being able to order them. Makes sense when I think of it. Although I don't know why Access doesn't just pull all records through at once, instead of getting the records one at a time.
I would try setting the Recordset Type to Snapshot (on the Data tab of the Form's property sheet and/or the property sheet of the query you are using for the form source)
In Access 2003, can we create stored procedure or function?
For Access 2003, the answer is no.
Access 2010 does have table triggers and store procedures. These are true engine level routines that run as a result of row updates. So forms or VBA recordset code or sql updates that cause a row modify will cause the store procedure and table level code to run. In fact, even external connections via ODBC from vb.net, or even VB6 will cause these store procedures to run.
However prior to Access 2010 you do not have store procedures if you use the default database engine. However, you can choose a different data engine then JET for your Access applications and when you do this then yes you can have store procedures, but you have to use the tools that come with whatever data base engine you have chosen to use with Access. So, keep in mind that just like when you build a web site, you then can go out and choose what database engine you use. The same goes for ms-access and you are free to go out and choose a database engine that has store procedures to be used with Access.
As noted, the exception to this is that Access 2010 does have table level triggers and store procedures now.
Not "Stored Procedures" as such. You can create saved queries and call those from Access in the same way as stored procs form Sql Server. The limitations that the saved queries have are that you cannot use control of flow code (such as If Else or Case When) and you can only save one command at a time.
The simplest way to create saved queries is to open up Access, go the Query tab and create a new query in Design View. Close the Show Tables dialogue box and switch to SQL View. Using the example above, type in the first part of the SQL clause:
INSERT INTO Addresses ( Organisationname, AddressLine1, AddressLine2,
AddressLine3, City, StateCounty, CountryID, PostCodeZip, SwitchboardNo,
FaxNo, Email, Website, RecordStatus, LastUpdated, LastUpdateBy )
Values
Now open the brackets and create the parameter place holders. These are always in square brackets ( [ ] ), which tells Access to expect a value as a parameter. You can put anything you like within the square brackets. [p1], [p2], [p3] etc are my choice, so the final query will look like this:
INSERT INTO Addresses ( Organisationname, AddressLine1, AddressLine2,
AddressLine3, City, StateCounty,CountryID, PostCodeZip, SwitchboardNo, FaxNo,
Email, Website, RecordStatus, LastUpdated, LastUpdateBy ) Values ([p1],[p2],[p3],
[p4],[p5],[p6],[p7],[p8],[p9],[p10],[p11],[p12], [p13],[p14],[p15]);
If you Run the query, Access will prompt you for input for each field. Enter data against each field to test that the query is working. As for debugging, you've just done it. Save the query as something meaningful. This one is saved as qUpdateAddresses. As you save it, you may notice that Access automatically detects that this is an Append Query. Once you have verified that it works, close the database.
to run it from ASP.NET, look at this article, paying attention to the bit towards the end that's headed "Saved Queries":
http://www.mikesdotnetting.com/Article.aspx?ArticleID=26