table locked or in use when calling RunSQL - ms-access

I have some code which re-arranges some items on a form, but only one SQL query. All my tables aren't locked before the code runs but for some reason I get an error when running:
DoCmd.RunSQL ("Select * Into MasterTable From Year07 Where 'ClassName' = '7A'")
Error:
The database engine could not lock table because it is already in use by another person or process. (Error 3211) To complete this operation, a table currently in use by another user must be locked. Wait for the other user to finish working with the table, and then try the operation again.
Any ideas what I can do to stop the table being locked?

Is MasterTable included in your form's Record Source? If so, you can't replace it, or modify its structure, while the form is open.
Apart from the table lock issue, there is a logic error in the SELECT statement.
Where 'ClassName' = '7A'
The string, ClassName, will never be equal to the string, 7A. Therefore your SELECT can never return any records. If ClassName is the name of a field in your Year07 table, discard the quotes which surround the field name.
Where ClassName = '7A'

I'm guessing, but if you're using a form that is bound to MasterTable, you can't run a query to replace it with a new MasterTable while you've got it open in the form.
I would suggest that you get rid of the MakeTable query (SELECT INTO) and instead use a plain append query (INSERT). You'll want to clean out the old data before appending the new, though.
Basically, a MakeTable query is, in my opinion, something that does not belong in a production app, and any process that you've automated with a MakeTable query should be replaced instead with a persistent temp table that is cleared before the new data is appended to it.

I have seen this when you re-open a database after Access has crashed. Typically for me a reboot has fixed this.

What version of MSAccess? Not sure about newer ones, but for Access 2003 and previous, if you were sure nobody was in the database, you could clear up locks after a crash by deleting the .ldb file.

Related

Trying to track changes in my MS Access Database

I have a table set up to track when people place an order (Order_Tbl). I duplicated the table that I call my order_change_log and added a date/time field (default value set to now). I have a one to many relationship between the orderID and order_change_logID. The idea is that before update, I want the existing data to be inserted into the change log table. I went into the before update field and made the following statement:
CurrentDB.Execute “INSERT into Order_Change_Log SELECT * FROM Order_Tbl WHERE ChangeLog_ID =“”” & Me.ID & “”””
I keep getting “Invalid Outside Procedure” and I’m getting frustrated… Not sure what I’m doing wrong.
What you want to do is called a trigger. In access a table's triggers can be accessed and created from the table's design mode via [Create Data Macros] on the ribbon. You are pretty much forced to use the macro language to create the trigger.
As an aside it looks like you are setting the default date in Order_Change_Log. Leave that default blank as it is not needed here and in many other cases leads to bugs.
In this case we will be using the after-update macro. The Before-Update values are available using [Old]
For an older example of a trigger happening after Delete see MS Access trigger?
Example Table and Relationships:
After Update Trigger Macro:
Use the ribbon to save the macro and you are done. change some values in the Order_Tbl then refresh or open the Order_Change_Log table to see the results

Mysql drop table/create table sequence gives strange error

This situation makes no sense.
I have the following sequence of SQL operations in my php code:
DROP TABLE IF EXISTS tablename;
CREATE TABLE tablename;
Of course the php code does not look like that, but those are the commands being executed.
Every once in a while on the CREATE statement, the system returns "table already exists".
I would not think this could happen, unless it is some kind of delay in the dropping. The table is Innodb and I read that there could be processes using the table. However, the tablename has embedded within it a session_id for the user, because this table is somewhat transient and is dedicated to the specific user only--no other user can be using the table, and not even any other script can be using it. It is a "user-specific, script-specific" table. However, it is possible that the user could execute this script, go away to a different script, then come back to this script.
The describe code is in a routine that decides whether it can re-use the table, or whether it has to be recreated. If it has to be recreated, then the two lines execute.
Any ideas what is causing this error condition?
EDIT:
The problem with "actual code" is that sometimes it just leads to more questions that diverge from the actual point. Neverthess, here is a copy from the actual script:
$query1 = "DROP TABLE IF EXISTS {$_SESSION['tmpContact']}";
SQL($query1);
$memory_table = "CREATE TABLE {$_SESSION['tmpContact']}";
The SQL() function executes the command and has error handling.
Plan A: Check for errors after the DROP. There may be a clue there.
Plan B: CREATE TEMPORARY TABLE ... -- That will be local to the connection, so [presumably] you won't need the DROP.
$a = mysql_query("SELECT TABLE");
if($a != ''){}else{}
try mixing the php with the sql.

get statement which triggered trigger. Or other identifiers

I have a table (items in stock) which gets updated from several applications.
All queries are supposed to also set a field 'src' with some audit information (user and form), but some queries are not doing that.
I intend to create a trigger on update, which checks if the 'src' field is changed.
I would like to rollback the update and fire an error if the 'src' is not set, but also to log the query, so I better can identify the offending application.
Is the actual query text available to the trigger?
Or any other identifier?
All connections to the database are done via scripts on webservers, with one of two logins, but from a handfull of servers, so the ip of the server might be useful.
The connection information available is:
select *
from sys.dm_exec_connections as EC inner join
sys.dm_exec_sessions as ES on ES.session_id = EC.session_id
where EC.session_id = ##SPID
AFAIK you cannot get the triggering statement within a trigger.

Wrong order of SQL statements on InnoDB from Kettle

In Kettle, I use the following logic in a transformation, given some Strings X and Y as input:
[User Defined Java Expression] Generate ID
[Insert / Update] Update/Insert table set id = generatedId, name=X, company=Y where name = X; don't update the ID column
[Database Value Lookup]select id from table where name = X
Idea is to update existing entries in the table or create new ones and get the ID of the interesting row in the next step (which may be an existing one or the newly generated one).
This works fine when executed on MySQL + MyISAM but fails on MySQL + InnoDB, with all other parameters being identical. The last step fails when the row is just being inserted in the second step but works for rows already existing in the database. It seems as if the connection tries to execute the SELECT of the last step before the actual insert happened.
All parameters are set to default in the MySQL settings (MySQL 5.1 and 5.5 show the same behavior).
So my questions are: What are the relevant parameters in Kettle and/or MySQL? How can I guarantee that this works as expected? I cannot switch back to MyISAM.
just use the block rows step between the insert step and the next step. Then the step before the block will complete before the next step starts.
Well, after having evaluated different possibilities, three seem to be possible:
Write my own step which performs the select/insert in a transaction
Serialize the whole transformation in its properties (makes everything REALLY slow)
Use Codeks idea and use the blocking step
I went with the third option for now as everything else is not possible for the moment.
Make sure the transaction generated by Update/Insert is committed and the locks are released before doing the SELECT operation takes place. It looks like there are lock problems

MySQL UPDATE vs INSERT and DELETE

I am working on a web app project and there is a rather large html form that needs to have its data stored in a table. The form and insert are already done but my client wants to be able to load the saved data back into the HTML form and be able to change it, again, this is no problem, but I came across a question when going to do the update, would it be appropriate to just keep the insert query and then delete the old row if it was an edit?
Basically, what already happens is when the form is submitted all of the data is put into a table using INSERT, I also have a flag called edit that contains the primary key ID if the data is for an existing field being updated. I can handle the update function two ways:
a) Create an actual update query with all the fields/data set and use an if/else to decide whether to run the update or insert query.
b) Do the insert every time but add a single line to DELETE WHERE row=editID after the insert is successful.
Since the Delete would only happen if the INSERT was successful I don't run the risk of deleting the data without inserting, thus losing the data, but since INSERT/DELETE is two queries, would it be less efficient than just using an if/else to decide whether to run an insert or update?
There is a second table that uses the auto-increment id as a foreign key, but this table has to be updated every time the form is submitted, so if I delete the row in table A, I will also be deleting the associated rows from table b. This seems like it would be bad programming practice, so I am leaning towards option a) anyway, but it is very tempting just to use the single line option. The DELETE would basically be as follows. Would this in fact be bad programming practice? Aside from conventions, are there any reasons why this is a "never do that!" type of code?
if ($insertFormResults) {
$formId = mysql_insert_id();
echo "Your form was saved successfully.";
if(isset($_POST['edit'])){
$query = "DELETE FROM registerForm WHERE id='$_POST[edit]'";
$result = mysql_query($query);
}
}
Whilst the INSERT/DELETE option would work perfectly well I'd recommend against it as:
Unless you bundle the INSERT/DELETE
up into a single transaction, or
better yet encapsulate the
INSERT/DELETE up into a stored
procedure you do run the theoretical
risk of accumulating duplicates. If
you use a SP or a transaction you're
just effectively rewriting the UPDATE
statement which is obviously
inefficient and moreover will give
rise to a few WTF raised eyebrows
later by anyone maintaining your
code.
Although it doesn't sound like an
issue in your case you are
potentially impacting referential
integrity should you need that.
Furthermore you are loosing the
rather useful ability to easily
retrieve records in creation order.
Probably not a great consideration on
a small application, but you are
going to end up with a seriously
fragmented database fairly quickly
which will slow data retrieval.
Update is only one round trip to the server, which is more efficient. Unless you have a reason that involves the possibility of bad data, always default to using an UPDATE.
It seems to me that doing the delete is pointless, if you run an update in MySql it will only update the record if it is different that what is stored already, is there some reason why you would need to do a delete instead. I usually use a case(switch) to catch update/delete calls from the user,
<?php
switch (action) {
case "delete" :
block of coding;
if the condition equals value1;
break;
case "edit" :
block of coding;
if the condition equals value2;
break;
}
?>