How to know if ADOQuery.Post will change database? - mysql

I have a project in Delphi 7 that uses a database in MySQL to store some configuration.
Whenever I change a config, a "Save" button is enabled. The OnClick procedure in this button calls TADOQuery.Edit, Select the fields with the SQL property, TADOQuery.Open and set the various FieldsByName. In the end, it TADOQuery.Post the configuration and Requery it.
This works well, only if at least one of these fields is actually changed.
If, for example, I check a checkBox (originally unchecked) and then unCheck it again, the Save button would go enabled, but the actual data in database doesn't change. In this case, when I call Post, an Exception is raised.
I saw this question that would solve my problem, checking if there ara any modification, but as soon as I set the first field, the Modified property of TADOQuery becomes true, invalidating this solution.
Another option would be to check, before setting the field, if it will actually change, setting an flag to, in the end, actually post it or not. But, there are hundreds of fields to do that, which will be pretty boring to do.
A third alternative I thought is to create a new field in database with a "Last Modified" datestamp, which forces to always have at least one modification, but I prefer to not mess with the existing database.
Is there any other way to know if a TADOQuery.Post will trigger an exception, because no data has really changed? How can I solve this problem? Or there's a simple workaround for it?
The ADOQuery variable is dynamically created in the Save button's routine (and free'd in the end).

It would be a nice approach to use CheckBrowseMode() instead of Post().
ADOQuery1.CheckBrowseMode
CheckBrowseMode():
Automatically posts or cancels data changes when the active record changes.
You can read more about here:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/DB_TDataSet_CheckBrowseMode.html

Related

Power Automate updating expression automatically to wrong value?

Not sure if any one else has noticed this behavior in Power Automate. So I would click on a dynamic content expression, and see something I needed to fix like body('parse json')?['variable_1']?[variabl_2] but [variable_2] is not inside ['variable_1']. Then after deleting the ?['variable_1'] value and clicking update, then clicking the expression again it would pull up the old value, body('parse json')?['variable_1']?[variabl_2]. I had to delete the whole object body('parse json')?['variable_1']?[variabl_2] then go to Dynamic content and re-add it then update and then it worked. I believe it has to do with changing my Json Schema around or possibly about how the cache is done. Like if the dynamic content was created with the old schema where [variable_2] was in [variable_1] then it would keep correcting to the old version because you can't get [variable_2] without having ?[variable_1] in place. I'll try to recreate this phenomenon again but was curious if any of you had seen it? I think it means you need to delete variables related to old json schema or it may autocorrect based on old json schema it is pointing to.

MS Access "Write Conflict" error when adding new field to record source

I want to preface this by saying I don't have any real programming background, I'm just trying to update an existing database at work.
We have an access database and I want to add an additional Y/N checkbox to an existing form. The form updates a SQL table. Currently the record source is a SQL statement.
I can go to the SQL table, add a new field and make it Yes/No data type. There are other Yes/No fields in the table and the default settings for the new field are identical to the others. I next go and update the linked table through External Data in the ribbon. I can go into the table in Access and see the new field - so far, so good.
Next, go to the form design view and form properties, go to the record source, update the SQL statement to include the new field. (I've also tried this thru query builder, same result.) From here, I start to get the error.
If I go back to form view and change any data in the form and hit the next record button or save button, I get the Write Conflict error. "This record has been changed by another user since you started editing it..." The 'Save Record' button is greyed out. I am the only person accessing the database or SQL server.
I've tried to finish building the new button and linking it to the new field in control source (that went fine), but it didn't make any difference. If I go in to edit the record source and remove the new field, everything works again (but of course, the new field isn't in the control source list, so isn't linked to the check box).
Any ideas? Thanks.
A strong contender for the reason for your problem is the form itself.
Most likely the form is setup with a specific query as the Record Source. Its not to say that that is inherently incorrect, but it makes adding new columns to the source significantly more difficult.
The problem would likely be solved if you just changed the Record Source to reference the table itself, rather than a query, if that is in fact how it is referenced.
If Ms Access tries to pull data from a table using a query through a form it will inherently Pessimistically Lock the table in question, making it unable to be modified. However, you can usually still modify the table through the query itself, but you would need to add the column changes into that query first.
I'm not quite sure if I am making sense here, but something like this (for a table called "Table1"):
In theory, if the form is the problem... then if you closed it and tried to make modifications to the table, then the changes should work when the form is closed.
Someone else fixed it for me, but from what I understand, it was a communication issue between SQL and Access. Something with the setting of the null value in SQL not being set the way that Access could understand.
We had the issue narrowed down. When the new field was added to the table, you couldn't change any info directly in the table, but you could with the form.
If you added the new field to the form's record source, you couldn't edit any info at all.
Thanks for everyone's input.

Webmatrix - Conditional database changes?

So i have an issue, where that properties on my website are either active or inactive. A property is deemed as inactive by default, and i want it to only become active once it has met some criteria. For example, i only want it to become active when a description is provided, at least one rate has been applied, and only when it has a valid ZIP code assigned.
How would i achieve this, since a user might not populate all this information upon first registration, and may want to come back at a later date to finish updating before it becomes active.
The only way i can think of, is to run an "if" statement, each time i update information on a property, which i can work with, but i was wondering if there was any other conditional way of making this happen, where the database regularly checks to see if should set something to active?
Thanks, Gavin
If you were running a full version of SQL Server, you could accomplish this with a trigger and a bitflag column like VoidKing suggested. On the save the trigger would trigger and you would write a complex sql statement that test if all the needed fields are filled and set the bitflag to true or false depending.
I did something like this in a simpler way by having two save buttons. A "save" that didn't trigger any validation and a "Save and Release" button that applied validation to all the needed fields. Both buttons saved the data, but the save and release button would only save if the validation passed and it would save the bitfield "isActive" to 1 where the other save method would save it as a 0.
Might be a good approach else you are left with your checking logic on the single save button, which isn't a bad way to go either.

Handling #DELETED messages on records that have been deleted while a form is active

There may be a better way to do this, but currently, if the user enters i value that is not allowed (in this case, a project that has been closed), then it notifies them. However, because it's on a sub-form linked to the table, it automatically created a record anyway. This is how it's currently handled (if a bad input was entered):
Clear the fields of that record
Delete the record from the table
Requery / Refresh
Currently it works fine, except it leaves #DELETED in all the controls associated with the records. However, if I hit F5, it disappears. Is there a way to make it so the deleted record disappears (like how it does when F5 is hit) programmatically?
I think you have a couple options to handle this. The main thing is that you want to avoid deleting the record and try to handle it before it ever becomes a saved record. You should be able to do this using one of several different form events (not control events): Dirty, BeforeUpdate or BeforeInsert.
If you use the Dirty event, check to see if the project is closed and check to see if the record they are working on is a NewRecord. If both are true then try using Cancel = True and/or Me.Undo.
If you use the BeforeUpdate event instead, it works much the same way. You'll probably need to cancel the edits and undo the edits as I mentiond directly above, in which order I'm not sure.
I don't have a good way to test the BeforeInsert event at the moment but I think you can prevent new records from coming into existence inside this event by using Cancel = True.
If you cannot handle the record before it gets saved, and you must truly clear #DELETED from your form, you'll probably need to use a Me.Requery statement. Exactly how this will work depends on whether or not the form is bound and what it is bound to but it sounds like you are using a fairly standard Access form that is bound to a table or SQL statement so I believe the Requery statement should work.

Is there a way to override automatic record updating of Access 2007 forms created with Form Wizard?

I'm new to Access VBA, and have created a form using the Form Wizard that displays records in a table. That's a piece of cake.
The behavior that I get with the form, though, is that updates to the records occur automatically when I move around records.
What I'd like is to have the updates occur only when I click an "Update" button that I put in the form.
It seems like I can construct the form from scratch, update all of the (unbounded) controls programmatically, and then update the record from the controls programmatically, but this seems like too much work.
Is there a way to "turn off" the automatic updating behavior from within Access, or using VBA code?
Thanks!
As Robert suggested, you can avoid saving a changed record by canceling the before update event. The code would look something like this:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Me.Undo
Cancel = True
End Sub
However, that approach requires you discard any changes you've made to the record before you can move off it. Without Me.Undo, you can cancel the update, but Access won't allow you to move to a different record. You must either save or discard the changes to the current record before moving to another.
If you want to move to another record but not discard changes first, I think you need to try a disconnected recordset. It's an ADO recordset you create in memory, not bound to any data source. You can add a command button to save your changes on command. If it sounds useful, see this article by Danny Lesandrini at Database Journal: Create In-Memory ADO Recordsets
If users are accidentally changing data and moving record to record causing updates, maybe you should have an Edit button to only start editing when needed. You can use other suggested code to either undo the changes if they move to another record or prevent them from moving at all unless they save or cancel.
Is there a way to "turn off" the
automatic updating behavior from
within Access, or using VBA code?
You can try cancelling the Form.BeforeUpdate event, unless a flag is set. When the button is clicked, set the flag, set Form.Dirty to false (to save the data), and then clear the flag in the Form.BeforeUpdate event handler.
Why would you want to? Access works on a record by record basis. Not like Excel which only saves the spreadsheet when you choose to save or exit.
It sounds like you have a continuous form with multiple records on the screen. The only way to do this would be to use a "temporary" table and the save the contents of the "temporary" table to the permanent table once you're ready. However then you will lose the ability to determine if someone else has changed the records unless you do a lot more work.