How can i control the multiple users accessing the same database - vb.net

I am making my first project using vb.net and access. I am trying to develop a project in which the data of patients of the is added from different counters. what I developed is working fine when only one counter adds data in database but when two counters access the same database and try to save the record it gives error primary key can not be duplicate.
I doing what, first I am generating a primary key number i.e. patient no that is unique to every patient. patient no. is one increment to the last saved record. then the user enter (counter data entry operator) adds the patient details and then hit the save button.
In multi-user environment both the operators generate the same patient no. when they hit the new record button as both see the same last saved record. while saving the record one operator save the record successfully but other operator get the duplicate primary key error.
Pessimistic and optimistic locks are not working for me or i am not understanding how to use them.
rsS As New ADODB.Recordset
rsS.Open(str, conn, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockPessimistic)
What I have tried:
I also tried to solve this problem by saving the patient no. in another variable oldPatientno and beore saving the record checked if there is any change in the database if so then regenerate the patient no. but this is not working.

Related

Multiple users accessing a linked table occasionally see a message "Cannot update. Database or object is read-only"

We have a split MS Access database. When users log on, they are connected/linked to two separate Access database (one for the specific project they are working on and one for record locking (and other global settings)). The "locking" database is the one I need to find a solution for.
One of the tables "tblTS_RecordLocking", simply stores a list of user names and the recordID of the record they are editing. This never has more than 50 records - usually being closer to 5-10. But before a user can do anything on a record, it opens "tblTS_RecordLocking" to see if the record is in use (so it happens a lot):
Set recIOC = CurrentDb.OpenRecordset("SELECT tblTSS_RecordLocking.* FROM tblTSS_RecordLocking WHERE (((tblTSS_RecordLocking.ProjectID_Lock)=1111) AND ((tblTSS_RecordLocking.RecordID_Lock)=123456));", , dbReadOnly)
If it's in use, the user simply gets a message and the form/record remains locked. If not in use, it will close the recordset and re-open it so that the user name is updated with the Record ID:
Set recIOC = CurrentDb.OpenRecordset("SELECT tblTSS_RecordLocking.* FROM tblTSS_RecordLocking WHERE (((tblTSS_RecordLocking.UserName_Lock)='John Smith'));")
If recIOC.EOF = True Then
recIOC.AddNew
recIOC.Fields![UserName_Lock] = "John Smith"
Else
recIOC.Edit
End If
recIOC.Fields![RecordID_Lock] = 123456
recIOC.Fields![ProjectID_Lock] = 111
recIOC.Update
recIOC.Close: set recIOC=Nothing
As soon as this finishes, everything realting to the second database is closed down (and the .laccdb file disappears).
So here's the problem. On very rare occasions, a user can get a message:
3027 - Cannot update. Database or object is read-only.
On even rarer occasions, it can flag the db as corrrupt needing to be compressed and re-indexed.
I really want to know the most reliable way to do the check/update. The process may run several hundred times in a day, and whilst I only see the issue once every few weeks, and for the most part handle it cleanly (on the front-end), I'm sure there is a better, more reliable way.
I agree with mamadsp that moving to SQL is the best option and am already in the process of doing this. However, whilst I was not able to create a fix for this issue, I was able to find a work-around that has yet to fail.
Instead of having a single lock table in the global database. I found that creating a lock table in the project database solved the problem. The main benefit of this is that there are much fewer activities on the table. So, not perfect - but it is stable.

VB.net filtering access database

I need help, I am making application for one medical practice.
I have one database where are all patients and one more where is all services (text), something like subdatabase. And when I make profile for patient, than I need to add some text to access DB. I know how to add new value to database but I don't know how to display only values for this patient. When I click Save I can see every value in this second database, I need to filter it with Patient ID.

How to implement a key lookup for generated keys table in pentaho Kettle

I just started to use Pentaho Kettle for integration. Seems great so far, quite intuitive compared to Talend, which I was also investigating.
I am trying to migrate some customers without their keys. So I have their email addresses.
The customer may already exist in the database, so what I need to do is:
If the customer exists, add it's id to the imported field and continue.
But if the customer doesn't exist I need to get the next Hibernate key from the table Hibernate_Sequences and set it as the id.
But I don't want to always allocate a key, so I want to conditionally execute a step to allocate the next key.
So what I want to do, is in the flow execute the db procedure, which allocates the next key and returns it, only if there's no value in id from the "lookup id" step.
Is this possible?
Just posting my updated flow - so the answer was to use a filter rows component which splits the data on true/false. I really had trouble getting the id out of the database stored proc because of a bug, so I had to use decimal and then convert back to integer (which I also couldn't figure out how to do, so used a javascript component).
Yes it is. As per official documentation (i left only valuable information) "Lookup values are added as new fields onto the stream". So u need just to put step "Filter row" in Flow section and check for "id" which suppose to be added in "Existing Id Lookup" step.

MS Access manual Auto incrementing field

Im building a system for my company to keep track of internal orders, inbetween our warehouses, we have material that goes out warehouse 1 to warehouse 2 and we kind of lose track of how much of "x" is in warehouse 1 and how much in warehouse 2, so i want to implement this access db where a user fills a form and says: order 1: 500 of "x" order 2: 300 of "y". then another user fills an exit form where he says 1 of "x" going out, so i would need the program to keep track of total order and how much as gone out to fill order 1 and so on...
My idea here is to have both an order number and an id number for each of "x" everytime someoneone assembles 1 "x" they fill the form and print a label directly from the access (i have this part working already) while keeping a record of when it was assembled, who verified and what was verified (it will work as a quality control also).
What i dont know is how to program the db so when it reaches 500 of "x", the id number for "x" starts again from 1
This is the one major issue with my program right now, i'm not experienced in access db's or vba, but im getting there with a tip and a trick from here and there, so, no need to be careful with the technical language, i will google it if i have to :p
EDIT:
The table structure goes as follows:
1 table as the main table where I record the check that is made for every product, where I include the model of the product, the said ID that I want to reset after a number of products checked, and a concatenated field that includes most of this information to generate a qr code.
Then there is a table for the Order Number, which is connected to a form to record each new order with a date/time field, the order number itself and the number of products. This number of products must then be called from the code that will count how many products have been checked to date and keep the order number field updated so we can keep track of the order.
Then there is another minor table just to get values for the form, the product models
Thank you for your answers ;)
See this MSDN Documentation
Unfortunately in Access, you cannot 'reset' an ID field, unless you move the records to a newly created table and use that table for every 500 records.
As for the user control and login form, I'm afraid those are separate questions that must be asked in a different thread.
To get you started:
You can set the RecordSource of a form to a table, and when users make entries, the data will be saved to the table. You can also use a form with controls (text boxes, comboboxes, etc.) and create a button that runs a query to insert these records into a table.
The login piece - you can encrypt the database with a password. That may/may not be sufficient.
I would suggest you change your schema, if possible. Something like the following:
Orders
OrderID (Autonumber)
ProductID (link to your Products table)
QuantityRequested
Deliverables
DeliverableID (Autonumber)
OrderID (link to your Orders table)
SequenceNumber: in the BeforeInsert event set this value equal to:
DCount("*", "Deliverables", "OrderID=" & Me.OrderID) + 1
I'm assuming that your form has a control named OrderID that is bound to the OrderID field of the Deliverables table.
The code uses the DCount() function to get the count of all the other deliverables that have already been created for this order. If this is the first deliverable, DCount() will return 0. It then adds 1 to this count to get the sequence number of the next deliverable.
If the new SequenceNumber is greater than the quantity requested, you could display a message saying that the order has been filled and cancel the creation of the Deliverable record.
This is just one approach and it is not a complete solution. I'm assuming that once assigned a sequence number a deliverable cannot be deleted. You might need to make allowances for deliverables that get lost or damaged. You could incorporate a status field to the Deliverable table to deal with this, but you would still need to make a decision about what to do with the SequenceNumber.

What do I gain by adding a timestamp column called recordversion to a table in ms-sql?

What do I gain by adding a timestamp column called recordversion to a table in ms-sql?
You can use that column to make sure your users don't overwrite data from another user.
Lets say user A pulls up record 1 and at the same time user B pulls up record 1. User A edits the record and saves it. 5 minutes later, User B edits the record - but doesn't know about user A's changes. When he saves his changes, you use the recordversion column in your update where clause which will prevent User B from overwriting what User A did. You could detect this invalid condition and throw some kind of data out of date error.
Nothing that I'm aware of, or that Google seems to find quickly.
You con't get anything inherent by using that name for a column. Sure, you can create a column and do the record versioning as described in the next response, but there's nothing special about the column name. You could call the column anything you want and do versioning, and you could call any column RecordVersion and nothing special would happen.
Timestamp is mainly used for replication. I have also used it successfully to determine if the data has been updated since the last feed to the client (when I needed to send a delta feed) and thus pick out only the records which have changed since then. This does require having another table that stores the values of the timestamp (in a varbinary field) at the time you run the report so you can use it compare on the next run.
If you think that timestamp is recording the date or time of the last update, it does not do that, you would need dateTime fields and constraints (To get the orginal datetime)and triggers (to update) to store that information.
Also, keep in mind if you want to keep track of your data, it's a good idea to add these four columns to every table:
CreatedBy(varchar) | CreatedOn(date) | ModifiedBy(varchar) | ModifiedOn(date)
While it doesn't give you full history, it lets you know who and when created an entry, and who and when last modified it. Those 4 columns create pretty powerful tracking abilities without any serious overhead to your DB.
Obviously, you could create a full-blown logging system that tracks every change and gives you full-blown history, but that's not the solution for the issue I think you are proposing.