Does Microsoft Access 2003 contain sets or multisets? - ms-access

I'm trying to confirm or deny whether you can define a table column in MS Access 2003 as a set. It seems this is implemented in Office 2007 - you can define a column to have a 'multi-select list' in the query/lookup, but this feature appears to be unique to the new access 2007 file format as far as I can determine.
Worded another way, does MS Access 2003 have the equivalent to the SQL statement:
CREATE TABLE mytable (foo VARCHAR(10), bar VARCHAR(5) MULTISET);
Or is there a clever workaround to achieve something similar? I would accept an answer providing information on any collection constructors in Access 2003.

Are you referring to the Access Database Engine's multivalued data types? If so then yes, these are new to the ACE (2007) version of the engine and are not available in Jet 4.0 being Access2003's version of the engine.
FWIW I tried your SQL in Access2007 using ANSI-92 Query Mode (OLE DB, engine type = 5) and the MULTISET keyword wasn't recognized.
Note you may not need nor want multivalued types. One particular criticism is that Access Database SQL DML expressions service hasn't been altered to take account of multivalued types. Also, see this article Multivalued datatypes considered harmful:
both Suraj [Poozhiyil, the MS Access
Program Manager] and I agree
wholeheartedly that developers do not
need to use multi-valued fields.
People who understand databases
already have a good way of
implementing many to many
relationships and will gain no benefit
from multi-valued fields.
So, my clear and certain advice to
developers is not to use multi-valued
fields. They have nothing to offer us
except potential pain.
UPDATE:
MULTISET is a new datatype officially
beginning with SQL:2003 so I'm
guessing part of the reason for adding
it in Access 2007 is to be fully
compliant with the SQL standard
That's almost amusing. The Access Team have shown no interest in adding SQL syntax that is compliant with any SQL Standard.
[When the SQL Server team were modifying Jet for its 4.0 release they wanted to attain SQL-92 compliance but were prevented from doing so by the Windows team whose components were reliant on some features remaining non-compliant... but that's another story. The Access Team have their own private folk of the code base so they've no such excuse... unless the SharePoint Team now has undue influence? I digress...]
Consider this quote from the document about the SQL2003 Standard:
Values of a MULTISET type can be
created either by enumerating the
individual elements or by supplying
the elements through a query
expression; e.g.,
MULTISET[1, 2, 3, 4]
or
MULTISET(
SELECT grades
FROM courses
)
...Conversely, a multiset value can be
used as a table reference in the FROM
clause using the UNNEST operator.
The Access Team has not added any new expressions nor any operators to the ACE SQL DML syntax. So, no, this has nothing to do with SQL Standards and everything to do with SharePoint.
David W. Fenton: No, [support for
multivalued types] was added in the
ACCDB format (not the ACE, as
#onedaywhen says...)
Consider this quote from the Access Team's own blog:
The primary feature we added to the new
Access engine is support for “complex
data”.
It is definitely an engine feature!

Related

Is there any replacement for the InstrRev function in Microsoft Access 2016 for a calculated column?

I am attempting to create several calculated columns in a table with different parts of a parsed filename. Using the InstrRev function is critical to isolate the base file name or extension, but InstrRev is not supported in calculated columns.
I know that there are other ways to solve my problem that don't use calculated columns, but does anyone have a valid calculated column formula that could help me?
Access lets you use VBA functions (including user-defined functions) directly from within a SQL query - however they only work within an Access context - if you have another frontend for a JET (now ACE) database - or inside a computed/calculated column, they won't work - as you've just discovered.
Unfortunately Access (JET and ACE) have only a very meagre and anaemic selection of built-in functions, and the platform has now lagged-behind SQL Server (and even the open-source SQLite) significantly - Access 2016 has not made significant changes to its SQL implementation since Access 2000 (16 years of stagnation!) whereas SQL Server 2016's T-SQL language is so evolved it's almost unrecognizable compared to SQL Server 2000.
JET and ACE support the standard ODBC functions ( https://msdn.microsoft.com/en-us/library/bb208907(v=office.12).aspx ) however none of these perform a "reverse index-of" operation. Also absent is any form of pattern-matching function - though the LIKE operator works, it only returns a boolean result, not a character index.
In short: what you want to do is impossible.
This has been discovered by many people before you:
https://social.msdn.microsoft.com/Forums/office/en-US/6cf82b1b-8e74-4ac8-9997-61cad8bb9310/access-database-engine-incompatible-with-instrrev?forum=accessdev
He maintains a list of DAO/Jet/etc reserved words - and on that list you will see the InstrRev is a VBA() function, and is not a part of the Jet/Ace Engines.
using InStrRev() and similar functions in Jet/ACE queries outside of Access
As you have discovered, SQL queries executed from within Access can use many VBA functions that are not natively supported by the Jet/ACE dialect of SQL
That said, computed/calculated columns are only really of use in stored VIEW objects ("Queries" objects in Access parlance) - which in turn are used for user convenience, not for any programming advantage - especially as these are scalar functions that are evaluated for every row of data that the engine processes (making them potentially very expensive and inefficient to run).
...so the only real solution is to abandon computed/calculated columns and perform this processing in your own application code - but the advantage is that your program will likely be significantly faster.
...or don't use Access and switch to a different DBMS with better active support, such as SQLite (for an in-process database), SQL Server (now with LocalDb for in-process support), or VistaDB (proprietary, but 100% Managed code). Note that Access also supports acting as a front-end for a SQL Server "backend" data-store - where you could create a VIEW that performs this operation, then query the view from your Access code or other consuming client.
There is a workaround if you must: Create a duplicate column that contains the string-reversed value of your original column, then you can evaluate the ODBC LOCATE or JET SQL InStr functions on it and get the result you want (albiet, reversed) - but this would require double the storage space.
e.g.
RowId, FileName , FileNameRev
1 , 'Foo.txt', 'txt.ooF'
2 , 'Bar.txt', 'txt.raB'
Avoid any calculated field. It's a "super user" feature only, that will cause you nothing but trouble. Calculated fields - or expressions - belong in a query.
So create a simple select query:
Select
*,
InStrRev([FieldToCheck], "YourMatchingString") As StringMatch
From
YourTable
Save the query, and then use this whenever you need the table values and this expression.

MySQL: Alternate solution of SQL Server's HierarchyId datatype

My current application was built up in SQL Server 2008 server in JAVA with Hibernate and I had used HierarchyId data type for department hierarchy in my database.
I had written SQL queries to deal with HierarchyId datatype. And I also have n-Level of department tree structure.
Now I want to change my Database server from SQL Server 2008 to MySQL as per business requirement.
After feasibility checking I came with the solution that my whole application will migrate to MySQL database server except HierarchyId data type.
So my main challenge is to find alternate solution of HierarchyId data type with the minimal change in coding.
What is the best way to implement department hierarchy in my database?
Thanks...
I faced the similar situation when our team decided to migrate from MS-SQL to MySQL. We resolved the issue using the following steps:
Added a column of type varchar(100) to the same table in MS SQL.
Converted the hierarchyid from hexadecimal value to string using the hierarchyid.ToString() function as saved it in the newly created column using computed column functionality. for eg. 0x58 -> "/1/", 0x7CE0 -> "/3/7/".
The level of the entity is equal to no-of '/''s minus 1.
These columns could be migrated to the MySQL.
The IsDesendantOf() and is method was replaced with LIKE function of string concaenated with '%'.
Thus we got rid of the hierarchyid functionality in MySQL.
Whenever we face such an issue, we just need to ask ourselves, what would we have done if this functionality would not have been provided by the tool we use. We generally end up getting the answer optimally.
Mysql has no equivalent that I'm aware of, but you could store the same data in a varchar.
For operations involving the HierarchyId, you're probably going to have to implement them yourself, probably as either user defined functions or stored procedures.
What sqlserver does looks like the "materialized path" method of storing a hierarchy. One example of that in mysql can be seen at http://www.cloudconnected.fr/2009/05/26/trees-in-sql-an-approach-based-on-materialized-paths-and-normalization-for-mysql/

How do I quote a reserved word in SQL so it works across all the common database systems?

Say I have a table call ‘users’ with a column ‘order’ and I wish my application code to work across all the database systems out there.
Assume that it is impractical to change the database schema. Even if the schema was change, one of the main database engine will come up with yet another reserved word, so stopping the app working when a database engine is updated.
I would rather not have to process the SQL strings to convert them into the correct form for each database.
'How to find if a column name is a reserved keyword across various databases' partly overlaps with this question.
('Syntax error due to using a reserved word as a table or column name in MySQL' is the reference question for MySQL.
)
You have to test on everything you are going to support, so "all the database systems out there" is not in realty an option.
To be more realistic, you can decide which DBMS you want to support, and write a subset of SQL which they are all happy with, and test them with automated tests.
For example, you might consider:
MySQL
Postgres
MS SQL Server
Oracle
I believe these all support ANSI double-quotes for quoting names, so if you quote all names all the time then you have one less thing to worry about.

Use Powershell to create access 2007 Queries?

I have been following Richard Siddaway's Awesome Series on Powershell+Access2007.
Unfortunately it ends before discussing creating/running/modifying access 2007 queries in powershell. How could this be done?
The cited series of articles uses a definition of stored procedure that is problematic. It says:
An SP is a piece of code that we have
defined, and saved in the database".
While this may be correct in a metaphorical sort of way, it's incorrect for Access/Jet/ACE. There is no CODE in the objects in a Jet/ACE database that are referred to by the generic term "procedure. In Access/Jet/ACE, a "procedure" is just a stored QueryDef, as there is no procedural code allowed. I don't know if the OLEDB interface restricts it or not, but my guess is that PROCEDURE means DML query and VIEW means SELECT.
So (and I'm just guessing here -- I'm an Access developer so have no need for doing any of this externally), if you want to create/update a DML QueryDef, you'd use the PROCEDURE keyword and the relevant DML for creating/altering PROCEDUREs. Likewise, with SELECTs, you'd use VIEW (I'm assuming).

Migration issue from MS-Access 2003 to MS-Access 2010

I work for a company where we likely going to update from Access97/2003 to Access2010.
After playing around with a prototype, I have found an issue when using Access 2010 with databases created in Access 2003.
Under some conditions, existing queries/SQL's in Access 2003 will become unusable in Access 2010. Here a small example:
Tablename: Parameters Field names: Number, Value
A query created with Access 2003 query designer:
SELECT Parameters.Value
FROM [Parameters]
WHERE (((Parameters.Number)=100));
this works fine with Access 2003.
In Access 2010 a error is raised: Syntax error in PARAMETER clause
A workaround for the error is to change the view in Access 2003. Here we get rid of the brackets:
SELECT Parameters.Value FROM [Parameters] WHERE Parameters.Number=100;
This will work in Access 2010 but the query remains unchangeable in the designer, because the query designer creates the syntax shown above.
The reason for this error is in fact the use of the reserved word 'Number', which shoudn't be used when you start to build a table or query, but for a migration with hundreds of existing databases, it is very likely or at least a risk to change the Access version without a complete test.
My idea is to write a small program which opens all the existing views and the tables to check if they work fine.
Anyway, dose anybody have a better solution for this, or is there a tool to check MS-Access 2003 databases to be compatible with Access 2010?
Many thanks in advance
Jörg
Parameters, Value, and Number are all reserved words. You may be right that Number is the culprit here; I would have suspected Parameters as more likely to confuse Access in a query.
"For a migration with hundreds of existing databases", first evaluate them with Allen Browne's Database Issue Checker Utility. In addition to the reserved words issue, it will give you an idea of other potential problem areas. Whether those issues will be more troublesome in Access 2010 than in 2003 is an open question.
However I don't see an easy solution for your predicament. You have hundreds of databases with perhaps thousands of tables and queries ... if they routinely incorporate reserved words for table and field names, as well as other object names ... your situation is miserable.
Experiment on a copy of an existing database. Turn on "track name autocorrect" and let it build the object dependencies. Change the table definitions to eliminate reserved words. Then see how much extra work you need to find and fix the items autocorrect didn't do for you. But don't leave autocorrect turned on in any application you release to your users.