In MS-Access is there any way to bypass/override/easily temporarily disable data validation of an INSERT SQL statement - sql

We have many tables with lots of fields that have data validation on them. When running an SQL insert statement to append imported data to these tables in the event of a data validation error they fail with the extremely helpful error message "27 records could not be added do to validation rule violations".
Tracking down these violations is very time consuming, so I am wondering if there is a way to do ANY of the following:
1) Find out the record and field(s) that caused the validation error programmatically
2) Override data validation during import so that people can afterwards look through the table to find the issues highlighted
3) Disable and then re enable validation for the same effect (short of looping through all columns, disabling data validation while saving the settings, then after the insert loop through again and re enable it for each column).
4) Some other suggestion I haven't thought of because it is past 10:00 pm here.
Any help would be very much appreciated.

No, Access does not allow validation rules to be disabled or overridden.
A separate import table is the best alternative that would facilitate possibilities #1 and #2.
Copy the destination table structure to a new table. You can do this with Copy (Ctrl+C) and Paste (Ctrl+V) within the navigation panel.
Alter the copied table definition by removing all validation rules and constraints.
Pay special attention to the primary key for the destination table.
If the primary key is an AutoNumber column, then go ahead and keep this column in the import table as the primary key. Just be aware that this value will be an arbitrary, temporary number used only for import row identification. Eventually the destination table will have a new unique value assigned.
If the primary key is composed of meaningful data columns, I suggest removing the primary key and unique constraint. Instead, add an additional AutoNumber primary key column just for importing.
If there is no primary key, you probably want to consider adding one and reviewing proper table normalization. As before, at least add an AutoNumber primary key as already described.
Define an import process. Some or all of this could be automated via code / macros.
Clear import table of existing data.
Import external data into the import table.
Copy rows from the import table to the permanent table.
The easiest method is probably an SQL INSERT INTO statement. Within the Access Query designer, an Append Query is the same thing as the INSERT INTO statement.
Alternative methods are to use VBA to loop through rows via RecordSet objects.
Run one or more comparison queries to detect and report rows which failed the copy operation.
This assumes that the data has a unique field or fields that can be used to distinguish rows from each other, both for the imported data as well as existing data in permanent table.
If the data does NOT have identifying fields, the only viable option is probably to loop through a RecordSet object in VBA code since a RecordSets can be used to select and operate on individual rows. But SQL statements operate on entire sets of data and rely on unique values to distinguish between rows of data.
Aside from problems verifying imported data, one should probably question the general usefulness and/or validity of the data rows if they have no individual identity.
For any import row which fails the copy operation, do one or more of the following, recursively improving the process and building a set of validations (queries and/or code) that you can automate.
Manually inspect data and try to determine failure reasons.
Write a validation query or set of validation queries which identify import rows that do not satisfy validation rules or constraints of the permanent table.
Possibly write additional queries which "massage" data into the permanent table, or which report on bad data to be fixed manually or researched further.

Related

Should I apply type 2 history to tables with duplicate keys?

I'm working on a data warehouse project using BigQuery. We're loading daily files exported from various mainframe systems. Most tables have unique keys which we can use to create the type 2 history, but some tables, e.g. a ledger/positions table, can have duplicate rows. These files contain the full data extract from the source system every day.
We're currently able to maintain a type 2 history for most tables without knowing the primary keys, as long as all rows in a load are unique, but we have a challenge with tables where this is not the case.
One person on the project has suggested that the way to handle it is to "compare duplicates", meaning that if the DWH table has 5 identical rows and the staging tables has 6 identical rows, then we just insert one more, and if it is the other way around, we just close one of the records in the DWH table (by setting the end date to now). This could be implemented by adding and extra "sub row" key to the dataset like this:
Row_number() over(partition by “all data columns” order by SystemTime) as data_row_nr
I've tried to find out if this is good practice or not, but without any luck. Something about it just seems wrong to me, and I can't see what unforeseen consequences can arise from doing it like this.
Can anybody tell me what the best way to go is when dealing with full loads of ledger data on a daily basis, for which we want to maintain some kind of history in the DWH?
No, I do not think this would be a good idea to introduce an artificial primary key based on all columns plus the index of the duplicated row.
You will solve the technical problem, but I doubt there will be some business value.
First of all you should distinct – the tables you get with primary key are dimensions and you can recognise changes and build history.
But the table without PK are most probably fact tables (i.e. transaction records) that are typically not full loaded but loaded based on some DELTA criterion.
Anyway you will never be able to recognise an update in those records, only possible change is insert (deletes are typically not relevant as data warehouse keeps longer history that the source system).
So my todo list
Check if the dup are intended or illegal
Try to find a delta criterion to load the fact tables
If everything fails, make the primary key of all columns with a single attribute of the number of duplicates and build the history.

Computed Columns In Azure SQL Server 2016 Temporal Tables

I am looking at creating temporal tables https://msdn.microsoft.com/en-us/library/mt604462.aspx in our database but I cant on a couple of tables that have computed columns.
The error message returned is rather self explanatory
"Computed column is defined with a user-defined function which is not allowed with system-versioned table"
but I was hoping there was a way to exclude or ignore columns from being tracked?
I have tried dropping the computed column creating the history table then adding the computed column back into the table but this didn't work.
Any help is appreciated.
Thanks
Edit -
I wasn't able to find a way to ignore columns from being tracked but we were able to refactor out the columns that used UDFs thus enabling us to use temporal tables.
I was struggling with adding a computed column to an existing system-versioned table. In case anyone else with a similar problem lands here, I finally realized that the history table doesn't treat the column the same way. It ends up being similar to having an IDENTITY column on the base table, but that would result in a regular INT field on the history table.
If you are attempting to add a computed column to a system-versioned (temporal) table:
First turn off system versioning
Then add your computed column to the base table
Verify the "type" of the resulting computed column
Add the column with the appropriate static type to the history table
Turn system versioning back on (DO NOT FORGET TO SPECIFY THE HISTORY TABLE)
I find it rather odd that you can accidentally omit the history_table when turning system versioning back on. I'd expect either it would resume versioning to the same table OR throw some kind of error considering it might be a bit unexpected behavior.
#pasquale-ceglie - I don't have enough reputation to comment, but I wanted to expand on what you said. You should be able to use most computed columns with temporal tables, just more manually. Basically you can't copy the schema definition with the computed columns, you can however replicate the resulting columns and generate the appropriate history table before trying to turn everything on. The definitions are just a bit different between the two tables (was quite confusing to me at first). I subscribed here, ping me if the above isn't clear and are curious.
System-versioned table schema modification fail because adding computed column while system-versioning is ON is not supported, so for the same reason you can't transform a regular table into a temporal one if there are computed columns on it.
Hope will help,

Changing a table's primary key column referenced by foreign key in other tables

In our DB (on SQL Server 2005) we have a "Customers" table, whose primary key is Client Code, a surrogate, bigint IDENTITY(1,1) key; the table is referenced by a number of other tables in our DB thru a foreign key.
A new CR implementation we are estimating would require us to change ID column type to varchar, Client Code generation algorithm being shifted from a simple numeric progression to a strict 2-char representation, with codes ranging from 01 to 99, then progressing like this:
1A -> 2A -> ... -> 9A -> 1B -> ... 9Z
I'm fairly new to database design, but I smell some serious problems here. First of all, what about this client code generation algorithm? What if I need a Client Code to go beyond 9Z code limit?
The I have some question: would this change be feasible, the table being already filled with a fair amount of data, and referenced by multiple entities? If so, how would you approach this problem, and how would you implement Client Code generation?
I would leave the primary key as it is and would create another key (unique) on the client code generated.
I would do that anyway. It's always better to have a short number primary key instead of long char keys.
In some situation you might prefer a GUID (for replication purposes) but a number int/bigint is alway preferable.
You can read more here and here.
My biggest concern with what you are proposing is that you will be limited to 360 primary records. That seems like a small number.
Performing the change is a multi-step operation. You need to create the new field in the core table and all its related tables.
To do an in-place update, you need to generate the code in the core table. Then you need to update all the related tables to have the code based on the old id. Then you need to add the foreign key constraint to all the related tables. Then you need to remove the old key field from all the related tables.
We only did that in our development server. When we upgraded the live databases, we created a new database for each and copied the data over using a python script that queried the old database and inserted into the new database. I now update that script for every software upgrade so the core engine stays the same, but I can specify different tables or data modifications. I get the bonus of having a complete backup of the original database if something unexpected happens when upgrading production.
One strong argument in favor of a non-identity/guid code is that you want a human readable/memorable code and you need to be able to move records between two systems.
Performance is not necessarily a concern in SQL Server 2005 and 2008. We recently went through a change where we moved from int ids everywhere to 7 or 8 character "friendly" record codes. We expected to see some kind of performance hit, but we in fact saw a performance improvement.
We also found that we needed a way to quickly generate a code. Our codes have two parts, a 3 character alpha prefix and a 4 or 5 digit suffix. Once we had a large number of codes (15000-20000) we were finding it to slow to parse the code into prefix and suffix and find the lowest unused code (it took several seconds). Because of this, we also store the prefix and the suffix separately (in the primary key table) so that we can quickly find the next available lowest code with a particular prefix. The cached prefix and suffix made the search almost fee.
We allow changing of the codes and they changed values propagate by cascade update rules on the foreign key relationship. We keep an identity key on the core code table to simplify the update of the code.
We don't use an ORM, so I don't know what specific things to be aware of with that. We also have on the order of 60,000 primary keys in our biggest instance, but have hundreds of tables related and tables with millions of related values to the code table.
One big advantage that we got was, in many cases, we did not need to do a join to perform operations. Everywhere in the software the user references things by friendly code. We don't have to do a lookup of the int ID (or a join) to perform certain operations.
The new code generation algorithm isn't worth thinking about. You can write a program to generate all possible codes in just a few lines of code. Put them in a table, and you're practically done. You just need to write a function to return the smallest one not yet used. Here's a Ruby program that will give you all the possible codes.
# test.rb -- generate a peculiar sequence of two-character codes.
i = 1
('A'..'Z').each do |c|
(1..9).each do |n|
printf("'%d%s', %d\n", n, c, i)
i += 1
end
end
The program will create a CSV file that you should be able to import easily into a table. You need two columns to control the sort order. The new values don't naturally sort the way your requirements specify.
I'd be more concerned about the range than the algorithm. If you're right about the requirement, you're limited to 234 client codes. If you're wrong, and the range extends from "1A" to "ZZ", you're limited to less than a thousand.
To implement this requirement in an existing table, you need to follow a careful procedure. I'd try it several times in a test environment before trying it on a production table. (This is just a sketch. There are a lot of details.)
Create and populate a two-column table to map
existing bigints to the new CHAR(2).
Create new CHAR(2) columns in all the
tables that need them.
Update all the new CHAR(2) columns.
Create new NOT NULL UNIQUE or PRIMARY KEY constraints and new FOREIGN KEY constraints on the new CHAR(2) columns.
Rewrite user interface code (?) to target the new columns. (Might not be necessary if you rename the new CHAR(2) and old BIGINT columns.)
Set a target date to drop the old BIGINT columns and constraints.
And so on.
Not really addressing whether this is a good idea or not, but you can change your foreign keys to cascade the updates. What will happen once you're done doing that is that when you update the primary key in the parent table, the corresponding key in the child table will be updated accordingly.

Design Pattern to add columns in database table dynamically

The user wants to add new fields in UI dynamically. This new field should get stored in database and they should be allowed to perform CRUD on it.
Now I can do this by specifying a XML but I wanted a better way where these new columns are searchable. Also the idea of firing ALTER statement and adding a new column seems wrong.
Can anyone help me with a design pattern on database server side of how to solve this problem?
This can be approached using a key value system. You create a table with the primary key column(s) of the table you want to annotate, a column for the name of the attribute, and a column for its value. When you user wants to add an attribute (say height) to the record of person 123 you add a row to the new table with the values (123, 'HEIGHT', '140.5').
In general you cast the values to TEXT for storage but if you know all the attributes will be numeric you can choose a different type for the value column. You can also (not recommended) use several different value columns depending on the type of the data.
This technique has the advantage that you don't need to modify the database structure to add new attributes and attributes are only stored for those records that have them. The disadvantage is that querying is not as straightforward as if the columns were all in the main data table.
There is no reason why a qualified business user should not be allowed to add a column to a table. It is less likely to cause a problem than just about anything else you can imagine including adding a new row to a table or changing. the value of a data element.
Using either of the methods described above do not avoid any risk; they are simply throwbacks to COBOL filler fields or unnecessary embellishments of the database function. The result can still be unnormalized and inaccurate.
These same business persons add columns to spreadsheets and tables to Word documents without DBAs getting in their way.
Of course, just adding the column is the smallest part of getting an information system to work, but it is often the case that it is perceived to be an almost insurmountable barrier. It is in fact 5 min worth of work assuming you know where to put it. Adding a column to the proper table with the proper datatype is easy to do, easy to use, and has the best chance of encouraging data quality.
Find out what the maximum number of user-added fields will be and add them before hand. For example 'User1', 'User2', 'User3', 'User4'...etc. You can then enable the fields on the UI based on some configurable settings.

Normalization Help

I am refactoring an old Oracle 10g schema to try to introduce some normalization. In one of the larger tables, there is a text field that has at most, 10-15 possible values. In my mind, it seems that this field is an example of unnecessary data duplication and should be extracted to a separate table.
After examining the data, I cannot find one relevant piece of information that could be associated with that text value. Basically, if I pulled that value out and put it into its own table, it would be the only field in that table. It exists today as more of a 'flag' field. Should I create a two-column table with a surrogate key, keep it as it is, or do something entirely different? Am I doing more harm than good by trying to minimize data duplication on this field?
You might save some space by extracting the column to a separate table. This is called a lookup table. It can give you a couple of other benefits:
You can declare a foreign key constraint to the lookup table, so you can rely on the column in the main table never having any value other than the 10-15 values you want.
It's easy to query for a concise list of all permitted values, by querying the lookup table. This can be faster than using SELECT DISTINCT on the main table's column. It also returns values that are permitted, but not currently used in the main table.
If you change a value in the lookup table, it automatically applies to all rows in the main table that reference it.
However, creating a lookup table with one column is not strictly normalization. You're just replacing one value with another. The attribute in the main table either already supports a normal form, or not.
Using surrogate keys (vs. natural keys) also has nothing to do with normalization. A lot of people make this mistake.
However, if you move other attributes into the lookup table, attributes that depend only on the lookup value and therefore would create repeating groups (violating 3NF) in the main table if you left them there, then that would be normalization.
If you want normalization break it out.
I think of these types of data in DBs as the equivalent of enums in C,C++,C#. Mostly you put them in the table as documentation.
I often have an ID, Name, Description, and auditing columns for them (eg modified by, modified date, create date, create by, active.) The description field is rarely used.
Example (some might say there are more than just 2)
Gender
ID Name Audit Columns...
1 Male
2 Female
Then in your contacts you would have a GenderID column which would link to this one.
Of course you don't "need" the table. You could have external documentation somewhere that says 1=Male, 2=Female -- but I think these tables serve to document a system.
If it's really a free-entry text field that's not re-used somewhere else in the database, and there's just a single field without repeated instances, I'd probably go ahead and leave it as it is. If you're determined to break it out I'd create a 'validation' table with a surrogate key and the text value, then put the surrogate key in the base table.
Share and enjoy.
Are these 10-15 values actually meaningful, or are they really just flags? If they're meaningful pieces of text and it seems wasteful to replicate them, then sure create a lookup table. But if they're just arbitrary flag values, then your new table will be nothing more than a mapping from one arbitrary value to another, and not terribly helpful.
A completely separate question is whether all or most of the rows in your big table even have a value for this column. If not, then indeed you have a good opportunity for normalization and can create a separate table linking the primary key from your base table with the flag value.
Edit: One thing. If there's some chance that one of these "flag" values is likely to be wholesale replaced with another value at some point in the future, that would be another good reason to create a table.