AS400 / DB2 cross-library query problem - sql

I'm querying an Iseries from ODBC in my app and am trying to perform a query that returns results from 2 tables. I need to join the tables but the tables are in different libraries. I don't want to use library identifiers in my query as my libraries change as I move from dev>qa>prod. However, I am certain that these tables will only be in these libraries and there will be no duplicates in other libraries. Is there a way to do this without specifying the Iseries library?
In essense, I want this:
select DISTINCT GIDNBR, VSL00100.GRNAME
FROM **QACOMMON**.CMPGRID2 CMPGRID2 INNER JOIN **QAVISLIVE**.VSL00100 VSL00100 ON VSL00100.GRNO=CMPGRID2.GIDNBR AND
VSL00100.GRSUB=CMPGRID2.GIDSUB AND
VSL00100.GRLOC=CMPGRID2.GIDLOC AND
VSL00100.GRPOOL=CMPGRID2.GIDPOL
to look like this:
select DISTINCT GIDNBR, VSL00100.GRNAME
FROM CMPGRID2 CMPGRID2 INNER JOIN VSL00100 VSL00100
ON
VSL00100.GRNO=CMPGRID2.GIDNBR AND
VSL00100.GRSUB=CMPGRID2.GIDSUB AND
VSL00100.GRLOC=CMPGRID2.GIDLOC AND
VSL00100.GRPOOL=CMPGRID2.GIDPOL
Any ideas?

You need to go into the configuration for your ODBC connection. On the connection you are using click on "Configure", then select the "Server" tab. The library list option is what you'll need to play with.
Based on your examples it looks like you need to have it say "QACOMMON QAVISLIVE". (with no quotes)
Also you will need to change the naming convention to *SYS instead of *SQL and make the default collection field blank. Make sure your system administrator sets the CURLIB parameter on the user profile you are using to where ever you want new files to go.
Then just save it and try it again. Unfortunately you'll have to either have different data sources or change the ODBC connection when you are switching around between test, production, and whatever else you have.

Related

How to query access table with a subdatasheet that requires parameters

I have been tasked with creating a method to copy the contents of an entire database to a central database. There are a number of source databases, all in Access. I've managed to copy the majority of the tables properly, 1:1. I'm using VBScript and ADO to copy the data. It actually works surprisingly well, considering that it's Access.
However
I have 3 tables that include subdatasheets (to those that don't know, a subdatasheet is a visual representation of a 1 to many relationship. You can see related records in another table inside the main table). When My script runs, I get an error. "No value given for one or more required parameters." When I open Access and try to run the same query that I've written in SQL, It pops up message boxes asking for parameters.
If I use the query wizard inside Access to build the select query, no parameters are required and I get no subdatasheet in the result set.
My question is this: how do I write a vanilla SQL query in my VBScript that does not require parameters and just gives me the data that I want?
I've tried copying the SQL from Access and running it through my VBScript and that doesn't seem to do the trick.
Any help is greatly appreciated!
As it turns out, you need to make sure that you've spelled all of the field names properly in your source query. If you've included additional fields that aren't actually in the source or destination table they'll need to be removed too.

Base crashing on union sql

I have 29 separate tables of council address data with identical field headers and thousands of entries. I am trying to find an address based on property id that should appear in at least one of the tables. I have been trying to use a union query;
SELECT "ST_NO_FROM","STREET","ST_TYPE"
FROM "list_address_points_break_o_day"
WHERE "PID" = 6413877
UNION
SELECT "ST_NO_FROM","STREET","ST_TYPE"
FROM "list_address_points_brighton"
WHERE "PID" = 6413877
Base is crashing every time I try to use this query and requires recovery. Does anyone have any idea why this is happening?
Be sure to use a split database setup and avoid embedded databases. From the link:
When the
file is "closed," the latest contents are repackaged into a single
zip-archive by *Office. This re-packaging process is problematic and
commonly leads to file-corruption...
So it's best to avoid these 'embedded database' files whenever
possible. This means avoiding the wizard dubbed 'Create a new
database' in Base.
HSQLDB (either 1.8 or a newer 2.x version) should be stable enough to handle the data. If the needs are very complex then a full-scale RDBMS such as MySQL could be used instead.

FM ExecuteSQL returns different results than direct database query

I am wondering if anyone can explain why I get different results for the same query string between using the ExecuteSQL function in FM versus querying the database through a database browser (I'm using DBVisualizer).
Specifically, if I run
SELECT COUNT(DISTINCT IMV_ItemID) FROM IMV
in DBVis, I get 2802. In FileMaker, if I evaluate the expression
ExecuteSQL ( "SELECT COUNT(DISTINCT IMV_ItemID) FROM IMV"; ""; "")
then I get 2898. This makes me distrust the ExecuteSQL function. Inside of FM, the IMV table is an ODBC shadow, connected to the central MSSQL database. In DBVis, the application connects via JDBC. However, I don't think that should make any difference.
Any ideas why I get a different count for each method?
Actually, it turns out that when FM executes the SQL, it factors in whitespace, whereas DBVisualizer (not sure about other database browser apps, but I would assume it's the same) do not. Also, since the TRIM() function isn't supported by MSSQL (from what I've seen, at least) it is necessary to make the query inside of the ExecuteSQL statement something like:
SELECT COUNT(DISTINCT(LTRIM(RTRIM(IMV_ItemID)))) FROM IMV
Weird, but it works!
FM keeps a cache of the shadow table's records (for internal field-id-mapping). I'm not sure if the ExecuteSQL() function causes a re-creation of the cache. In other words: maybe the ESS shadow table is out of sync. Try to delete the cache by closing and restarting the FM client or perform a native find first.
You can also try a re-connect to the database server via the Open File script step.
HTH

SQL statement against Access 2010 DB not working with ODBC

I'm attempting to run a simple statement against an Access DB to find records.
Data validation in the records was horrible, and I cannot sanitize it. Meaning, it must be preserved as is.
I need to be able to search against a string with white space and hyphen characters removed. The following statement will work in Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
Running it from an ODBC connection via PHP will not. It produces the following error:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
Creating a query in the database that runs the function and attempting to search its values indirectly causes the same error:
select * from dummy_indirect where Expr1 = 'ABCD1234';
I've attempted to use both ODBC drivers present. ODBCJR32.dll (03/22/2010) and ACEODBC.dll (02/18/2007). To my knowledge these should be current as it was installed with the full Access 2010 and Access 2010 Database Engine.
Any ideas on how to work around this error and achieve the same effect are welcome. Please note, that I cannot alter the database in way, shape, or form. That indirect query was created in another mdb file that has the original tables linked from the original DB.
* Update *
OleDB did not really affect anything.
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
I'm not attempting to use it as a web backend either. I'm not a sadomasochist.
There is a legacy system that I must support that does use Access as a backend. Data gets populated there from other old systems that I must integrate into more modern systems. Hence, the creation of an API with Apache/PHP that is running on the server supporting the legacy system.
I need to be able to search a table that has an alphanumeric case identifier to get a numeric identifier that is unique and tied to a generator (Autonumber in access). Users have been using it a trash box for years (inconsistent data entry with sporadic notations) so the only solution I have is to strip everything except alphanumeric out of both the field value and the search value and attempt to perform a LIKE comparison against it.
If not replace() which is access supported, what ODBC compatible functions exist that I can use do the same kind of comparison?
Just to recap, the Access db engine will not recognize the Replace() function unless your query is run from within an Access application session. Any attempt from outside Access will trigger that "Undefined function" error message. You can't avoid the error by switching from ODBC to OleDb as the connection method. And you also can't trick the engine into using Replace() by hiding it in separate query (in the same or another Access db) and using that query as the data source for your main query.
This behavior is determined by Access' sandbox mode. That linked page includes a list of functions which are available in the default sandbox mode. That page also describes how you can alter the sandbox mode. If you absolutely must have Replace() available for your query, perhaps the lowest setting (0) would allow it. However, I'm not recommending you do that. I've never done it myself, so don't know anything about the consequences.
As for alternatives for Replace(), it would help to know about the variability in the values you're searching. If the space or dash characters appear in only one or a few consistent positions, you could do a pattern match with a Like expression. For example, if the search field values consist of 4 letters, an optional space or dash, followed by 4 digits, a WHERE clause like this should work for the variations of "ABCD1234":
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
Another possibility is to compare against a list of values:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
However if your search field values can include any number of spaces or dashes at any position within the string, that approach is no good. And I would look real hard for some way to make the query task easier:
You can't clean the stored values because you're prohibited from altering the original Access db in any way. Perhaps you could create a new Access db, import the data, and clean that instead.
Set up the original Access db as a linked server in SQL Server and build your query to take advantage of SQL Server features.
Surrender. :-( Pull in a larger data set to your PHP client code, and evaluate which rows to use vs. which to ignore.
I'm not sure you can do this with ODBC and your constraints. The MS Access driver is limited (by design; MS wants you to use SQL Server for back ends).
Can you use OLEDB? that might be an option.

How can I create a schema alias in DB2 on System z?

Part of a reporting toolkit we use for our development is configured to always use the same schema (say XYZZY).
However, certain customers have stored their data in a different schema PLUGH. Is there any way within DB2/z to alias the entire schema XYZZY to refer to the objects in schema PLUGH?
The reporting toolkit runs on top of ODBC using the DB2 Connect Enterprise Edition or Personal Edition 9.1 drivers.
I know I can set up individual aliases for tables and views but we have many hundreds of these database objects and it will be a serious pain to do the lot. It would be far easier to simply have DB2 auto-magically translate the whole schema.
Keep in mind we're not looking for being able to run with multiple schemas, we just want a way to redirect all requests for database objects to a single, differently named, schema.
Of course, if there's a way to get multiple schemas on a per-connection basis, that would be good as well. But I'm not helpful.
I am guessing that by DB/2 schema you mean the qualifying name in some two part object name. For
example, if a two
part table name is: PLUGH.SOME_TABLE_NAME. You want to do define XYZZY as an
alias name for PLUGH so the reporting program can refer to the table as XYZZY.SOME_TABLE_NAME.
I don't know how to directly do that (schema names don't take on aliases as far as I am aware).
The objection you have to defining individual alias names
using something like:
CREATE ALIAS XYZZY.SOME_TABLE_NAME FOR PLUGH.SOME_TABLE_NAME
is that there are hundreds of them to do making it a real pain. Have you thought about
using a SELECT against the DB/2 catalogue to generate CREATE ALIAS statements for
each of the objects you need to refer to? Something like:
SELECT 'CREATE ALIAS XYZZY.' || NAME || ' FOR PLUGH.' || NAME
FROM SYSIBM.SYSTABLES
WHERE CREATOR = 'PLUGH'
Capture the output into a file then execute it. Might be hundreds of commands,
but at least you didn't have to write them.