Access validation rule violation update query across multiple tables - ms-access

I would like to create an update query to update a yes/no field in one table (called 'pmh' for past medical history) based on the numeric value of a field in another table (called 'bloods'). I am trying to populate a yes/no field for kidney disease based on a blood test result.
If I do this when both fields are in one table, it works. If I try and do it across two tables, I get a 'Validation rule violation' error message. Apart from being in one or two tables, the fields are exactly the same. There are no validation rules or zerolength criteria in either the tables or fields.
I wonder whether this is something to do with the join type in Relationships. I have set the join type to 2 ('Include ALL records from 'bloods' and only those records from 'pmh' where the joined fields are equal') - because I want to be able to see all patients with a value in the 'bloods' table.
The relationship between the tables is one-to-one - each patient has only one set of blood tests - the reason for not using one table is that the number of fields would be greater than 255.
I hope this makes sense - I have tried to make it as succinct as I can. Thanks everyone for your help, and let me know if you need any more information.

Sounds like data structure is not normalized. Saving calculated data is usually a bad idea. The Y/N value can be calculated when needed.
Join type set in relationships builder should not prevent update. Should provide attempted query for analysis. Is it like:
UPDATE pmh INNER JOIN bloods ON pmh.ID = bloods.ID SET pmh.fieldname = IIf([bloods.fieldname]="something", True, False);

Related

Multi-Table Query Not Updateable in MS Access

First post for me so please bear with me if I'm short on providing enough info.
I'm trying to put a query together that will be used as a subform on a project expense data entry form. As part of the query I want Access to pull the correct tax rates to calculate PST & GST correctly in calculated fields within the query. I have a query that consists of 5 tables:
tblProjectExpenseLineItems (PK: ExpenseLineItemID, FK: ProjectExpenseID)
tblProjectExpenses (PK: ProjectExpenseID, FK: ProjectNoID)
tblProjects (PK: ProjectNoID, FK: ClientID)
tblClientList (PK: Client ID)
tblTaxRate
Query design looks like this: qryProjectExpensesLineItemsExtended Query Design
The picture doesn't show it but the PSTTaxRate field is set to [tblTaxRate]![TaxRate] and the PST field is just the PST calculation on the expense line item.
I manually joined [tblClientList].[Province] to [tblTaxRate].[TaxJurisdiction]. These aren't related in the database relationships since neither fields are primary keys and I get the "indeterminate" relationship type. I have checked and confirmed that the values in these fields are in fact the same so results do show when I run the query.
The query fields are primarily from the tblProjectsExpensesLineItems table only since this is the table I want to update through the subform (I've tried adding the different PKs to see if that would change anything but no such luck). The only reason I have the other four tables is to get the [tblClientList].[Province] field so that I can pick up the location of the client and know which tax to charge. Where I live we've had our PST change a few times recently so I further filter the query using the [ExpenseDate] field to find the tax rate that fits between the [tblTaxRate].[StartDate] and [tblTaxRate].[EndDate] fields.
Things I've checked/read into:
I've checked that the table relationships have been set, are related to primary keys, and have "Enforce Referential Integrity" checked.
I've tried deleting tblTaxRate out of the query since it doesn't have an actual relationship. The query still isn't updateable and Access prompts me for the TaxRate, StartDate and EndDate fields when I run the query
I found a very detailed post here Why is my query not updateable? about reasons why queries aren't updateable. I'm pretty new to Access so I was able to rule out most of them, but some of them I don't quite understand (maybe something to do with the one-to-many and many-to-one relationships?)
Deleting all the tables except for the one I want to update. This of course makes the query updateable but Access prompts me for all the fields related to trying to find the tax rate.
I thought maybe an easy way out is to just manually enter tax rates but the database is being used for invoicing so I'm trying to eliminate potential for user input error.
I also thought this would be easier if I used form controls to do the heavy lifting but the tax calcs show up in many forms so I was hoping to keep the calcs at the query level so that I don't have to keep writing the calcs for every form and instead just reference the same query.
I'm at a total loss. I have the query responding properly but I can't do any data entry which is the sole purpose of the query! Any help is much appreciated!!
Scott

Access query is duplicating unique records / Linked table issues

I hope someone can help me with this:
I have a simple query combining a list of names and basic details with another table containing more specific information. Some names will necessarily appear more than once and arbitrary distinctions like "John Smith 1" and "John Smith 2" are not an option, so I have been using an autonumber to keep the records distinct.
The problem is that my query is creating two records for each name that appears more than once. For example, there are two clients named 'Sophoan', each with a different id number, and the query has picked up each one twice resulting in four records (in total there are 122 records when there should only be 102). 'Unique values' is set to 'yes'.
I've researched as much as I can and am completely stuck. I've tried to tinker with sql but it always comes back with errors, I presume because there are too many fields in the query.
What am I missing? Or is a query the wrong approach and I need to find another way to combine my tables?
Project in detail: I'm building a database for a charity which has two main activities: social work and training. The database is to record their client information and the results of their interactions with clients (issues they asked for help with, results of training workshops etc.). Some clients will cross over between activities which the organisation wants to track, hence all registered clients go into one list and individual tables spin of that to collect data for each specific activity the client takes part in. This query is supposed to be my solution for combining these tables for data entry by the user.
At present I have the following tables:
AllList (master list of client names and basic contact info; 'Social Work Register' and 'Participant Register' join to this table by
'Name')
Social Work Register (list of social work clients with full details
of each case)
Social Work Follow-up Table (used when staff call social work clients
to see how their issue is progressing; the register has too many
columns to hold this as well; joined to Register by 'Client Name')
Participants Register (list of clients for training and details of
which workshops they were attended and why they were absent if they
missed a session)
Individual workshop tables x14 (each workshop includes a test and
these tables records the clients answers and their score for each
individual test; there will be more than 20 of these when the
database is finished; all joined to the 'Participants Register' by
'Participant Name')
Queries:
Participant Overview Query (links the attendance data from the 'Register' with the grading data from each Workshop to present a read-only
overview; this one seems to work perfectly)
Social Work Query (non-functional; intended to link the 'Client
Register' to the 'AllList' for data entry so that when a new client
is registered it creates a new record in both tables, with the
records matched together)
Participant Query (not yet attempted; as above, intended to link the
'Participant Register' to the 'AllList' for data entry)
BUT I realised that queries can't be used for data entry, so this approach seems to be a dead end. I have had some success with using subforms for data entry but I'm not sure if it's the best way.
So, what I'm basically hoping to achieve is a way to input the same data to two tables simultaneously (for new records) and have the resulting records matched together (for new entries to existing records). But it needs to be possible for the same name to appear more than once as a unique record (e.g. three individuals named John Smith).
[N.B. There are more tables that store secondary information but aren't relevant to the issue as they are not and will not be linked to any other tables.]
I realised that queries can't be used for data entry
Actually, non-complex queries are usually editable as long as the table whose data you want to edit remains 'at the core' of the query. Access applies a number of factors to determine if a query is editable or not.
Most of the time, it's fairly easy to figure out why a query has become non-editable.
Ask yourself the question: if I edit that data, how will Access ensure that exactly that data will be updated, without ambiguity?
If your tables have defined primary keys and these are part of your query, and if there are no grouping, calculated fields (fields that use some function to change or test the value of that field), or complex joins, then the query should remain editable.
You can read more about that here:
How to troubleshoot errors that may occur when you update data in Access queries and in Access forms
Dealing with Non-Updateable Microsoft Access Queries and the Use of Temporary Tables.
So, what I'm basically hoping to achieve is a way to input the same data to two tables simultaneously (for new records) and have the resulting records matched together (for new entries to existing records). But it needs to be possible for the same name to appear more than once as a unique record (e.g. three individuals named John Smith).
This remark actually proves that you have design issues in your database.
A basic tenet of Database Design is to remove redundancy as much as possible. One of the reasons is actually to avoid having to update the same data in multiple places.
Another remark: you are using the Client's name as a Natural Key. Frankly, it is not a very good idea. Generally, you want to make sure that what constitutes a Primary key for a table is reliably unique over time.
Using people's names is generally the wrong choice because:
people change name, for instance in many cultures, women change their family name after they get married.
There could also have been a typo when entering the name and now it can be hard to correct it if that data is used as a Foreign Key all in different tables.
as your database grows, you are likely to end up with some people having the same name, creating conflicts, or forcing the user to make changes to that name so it doesn't create a duplicate.
The best way to enforce uniqueness of records in a table is to use the default AutoNumber ID field proposed by Access when you create a new table. This is called a Surrogate key.
It's not mean to be edited, changed or even displayed to the user. It's sole purpose is to allow the primary key of a table to be unique and non-changing over time, so it can reliably be used as a way to reference a record from one table to another (if a table needs to refer to a particular record, it will contain a field that will hold that ID. That field is called a Foreign Key).
The names you have for your tables are not precise enough: think of each table as an Entity holding related data.
The fact that you have a table called AllList means that its purpose isn't that well-thought of; it sounds like a catch-all rather than a carefully crafted entity.
Instead, if this is your list of clients, then simply call it Client. Each record of that table holds the information for a single client (whether to use plural or singular is up to you, just stick to your choice though, being consistent is hugely important).
Instead of using the client's name as a key, create an ID field, an Autonumber, and set it as Primary Key.
Let's also rename the "Social Work Register", which holds the Client's cases, simply as ClientCase. That relationship seems clear from your description of the table but it's not clear in the table name itself (by the way, I know Access allows spaces in table and field names, but it's a really bad idea to use them if you care at least a little bit about the future of your work).
In that, create a ClientID Number field (a Foreign Key) that will hold the related Client's ID in the ClientCase table.
You don't talk about the relationship between a Client and its Cases. This is another area where you must be clear: how many cases can a single Client have?
At most 1 Case ? (0 or 1 Case)
exactly 1 Case?
at least one Case? (1 or more Cases)
any number of Cases? (0 or more Cases)
Knowing this is important for selecting the right type of JOIN in your queries. It's a crucial part of the design assumptions when building your database.
For instance, in the most general case, assuming that a Client can have 0 or more cases, you could have a report that displays the Client's Name and the number of cases related to them like this:
SELECT Client.Name,
Count(ClientCase.ID) AS CountOfCases
FROM Client
LEFT JOIN ClientCase
ON Client.ID = ClienCase.ClientID
GROUP BY Client.Name
You've described your basic design a bit more, but that's not enough. Show us the actual table structures and the SQL of the queries you tried. From the description you give, it's hard to really understand the actual details of the design and to tell you why it fails and how to make it work.

Dynamic Condition Objects

In BO XI 3.1, is it possible to create a condition object that filters on multiple tables, without adding all of those tables to the query if they weren't already present?
For example, if I have several tables which all contain both current and historical data, and each table has a flag to indicate if the record is current or historical - can I create a single "Current Data" condition that filters all of such tables to pull only current data? The catch would be that the query might not be selecting from all of these tables, and I don't want the inclusion of the condition to add joins to tables I'm not selecting from.
In other words, can a condition check which tables are being used by the query and apply filters only on those tables?
You could add a self-restricting join to each of those tables, and use an #prompt function to ask whether to return current data or historical data. If you use the same text and same datatype for all of the prompts in each self-restricting join, the prompt will only be shown once, and will only be applied to the tables that are actually used in the generated query.
The self-restricting join could look something like:
<table>.<history_flag>
= #Prompt('Select current or historical data','A',{'C','H'}, Mono, constrained, , {'C'})
In the above example, we assume that the flag is an alphanumeric column (A) with values C or H ({'C','H'}). The user is only allowed to pick from these two values (constrained) and only one value can be chosen (Mono). The default choice is set to current data ({'C'}).
Have a look at the Universe Designer guide for the #prompt syntax. Self-restricting joins are explained in the same manual.

SQL to update column in modified table

I am a reasonably competent SQL programmer but my skills are still pretty much in the domain of simple INSERT, SELECT, UPDATE statements with an occasional LIKE etc thrown in. What I am currently trying to do is rather more complex. Here is the scenario.
I have three tables.
Table 1, *users* identifies users via a User ID, uid. Users can have one or more sub accounts
Table 2 *accounts* keeps a record of subaccounts for each user with, amongst other things the columns uid and sid where uid is the one defined in the *users* table.
Table 3, *data* is currently storing some data, in a data column that is being associated with a particular subaccount, sid.
The thing I have just realized is that there is no particular reason to block users from using those data across subaccounts. No problem - I can change my data subset search SQL to work with the uid instead. However, given the frequency of such searches, it seems well worth while simply sticking in a uid column in *data*.
To do that I would need to write some smart SQL that would get uid,sid pairs from the *accounts* table and use that information to update the newly created uid column in the data table. This I have to admit is beyond my knowledge of SQL.
I should mention that the system using these data is now in production and has several 100s of users so the option of just acting like they are not there is not available. Not terribly relevant I think but I should mention that uid and sid are alphanumeric strinsg with both columns being indexed.
I would be most grateful to anyone here who might be able to help out with it.
Mysql can do updates based on joins and based on reading of your schema here's what I'd do...
UPDATE accounts a, data d
set d.uid=a.uid
where a.sid=d.sid
and d.uid is NULL

Need help on Mysql Database Structure

I have 200 users each user will eventually have a "reviewINFO" table with certain data.
Each user will have a review every 3 to 4 months
So for every review, it creates a new row inside the "reviewINFO" table.
This is where i'm stuck. I'm not sure if I need to serialize a table inside each row or not.
Example:
-> links
"USER1reviewINFO"-row1->USER1table1
-row2->USER1table2
-row3->USER1table3
-row4->USER1table4
-row5->USER1table5
"USER2reviewINFO"-row1->USER2table1
-row2->USER2table2
-row3->USER2table3
-row4->USER2table4
-row5->USER2table5
using this method it will make a couple of thousand rows within two years. And I think its harder to manage.
"Userxtablex" is a table with dynamic rows of children names,ages,boolean
What i'm think of doing is serialize each USERxtable into its corresponding row.
Please help as I would not like to make this complicate or inefficient
Generally, you should never have to serialize data of this nature into a table row to accomplish what your goal is (which I am assuming is an implicit link between a user and a review)
What you need to do is key the reviews by a user_id such that all the reviews are packaged in one table, and relate numerically back to the users table.
Assuming you have an AUTO_INCREMENT primary key in the user table, all you would need is a user_id field in the reviews table that represents what user the review relates to. There is no need for a separate structure for each user, if that's what you are suggesting. Reviews can have date fields as well, so you can perform queries for a specific year or window of time.
You can then use a JOIN query to select out your data set relating to a particular user or review, and apply the usual WHERE clause to determine what result set you want to fetch.