Access Query resulting in #Error for one outcome - vba

I am pulling information via a query in access. Below is my code. The results populate when the "Pinacle Type" is "DOM" or "BOOK", but if the type is anything else, as stated by the IIF statement, I get #Error.
5_BeneBankID: IIf([Pinacle_Type]="DOM" Or "BOOK",Mid(Replace(Replace([BeneABA]," ",""),"-",""),1,11),Mid(Replace(Replace([Intl_BeneBankID]," ",""),"-",""),1,11))
Embedded in this statement is are also formatting parts but those work for the first instance. The BeneABA field is a bank ABA number so this is always numeric. The Intl_BeneBankID is what is known as a SWIFT code which is either all alpha or alphanumeric. Both have a maximum length of 11 characters.
Also, If I type the following, the Intl_BeneBankID POPULATES! which is why I am stumped:
5_BeneBankID: Intl_BeneBankID
relevant table

I'm not sure, as your description of the problem seems vague to me, but if you are getting #error on some rows, but not all, you probably have null fields in your data. This is a common problem in test data, not so often in production code, but needs to be handled. Try wrapping the fields with Nz() i.e. ((Replace(Nz([Intl_BeneBankID],"")... and see what you get.

Related

"Cannot construct data type datetime" when filtering data, but all values filtered DO have valid dates

I am convinced that this question is NOT a duplicate of:
Cannot construct data type datetime, some of the arguments have values which are not valid
In that case the values passed in are explicitly not valid. Whereas in this case the values that the function could be expected to be called upon are all valid.
I know what the actual problem is, and it's not something that would help most people that find the other question. But it IS something that would be good to be findable on SO.
Please read the answer, and understand why it's different from the linked question before voting to close as dupe of that question.
I've run some SQL that's errored with the error message: Cannot construct data type datetime, some of the arguments have values which are not valid.
My SQL uses DATETIMEFROMPARTS, but it's fine evaluating that function in the select - it's only a problem when I filter on the selected value.
It's also demonstrating weird, can't-possibly-be-happening behaviour w.r.t. other changes to the query.
My query looks roughly like this:
WITH FilteredDataWithDate (
SELECT *, DATETIMEFROMPARTS(...some integer columns representing date data...) AS Date
FROM Table
WHERE <unrelated pre-condition filter>
)
SELECT * FROM FilteredDataWithDate
WHERE Date > '2020-01-01'
If I run that query, then it errors with the invalid data error.
But if I omit the final Date > filter, then it happily renders every result record, so clearly none of the values it's filtering on are invalid.
I've also manually examined the contents of Table WHERE <unrelated pre-condition filter> and verified that everything is a valid date.
It also has a wild collection of other behaviours:
If I replace all of ...some integer columns representing date data... with hard-coded numbers then it's fine.
If I replace some parts of that data with hardcoded values, that fixes it, but others don't. I don't find any particular patterns in what does or doesn't help.
If I remove most of the * columns from the Table select. Then it starts to be fine again.
Specifically, it appears to break any time I include an nvarchar(max) column in the CTE.
If I add an additional filter to the CTE that limits the results to Id values in the following ranges, then the results are:
130,000 and 140,000. Error.
130,000 and 135,000. Fine.
135,000 and 140,000. Fine.!!!!
Filtering by the Date column breaks everything ... but ORDER BY Date is fine. (and confirms that all dates lie within perfectly sensible bounds.)
Adding TOP 1000000 makes it work ... even though there are only about 1000 rows.
... WTAF?!
This took me a while to decode, but it turns out that the SS compiler doesn't necessarily restrict its execution of the function just to rows that are, or could be, relevant to the result set.
Depending on the execution plan it arrives at, the function could get called on any record in Table, even one that doesn't satisfy WHERE <unrelated pre-condition filter>.
This was found by another user, for another function, over here.
So the fact that it could return all the results without the filter wasn't actually proving that every input into the function was valid. And indeed there were some records in the table that weren't in the result set, but still had invalid data.
That actually means that even if you were to add an explicit WHERE filter to exclude rows containing invalid date-component data ... that isn't actually guaranteed to fix it, because the function may still get called against the 'excluded' rows.
Each of the random other things I did will have been influencing the query plan in one way or another that happened to fix/break things.
The solution is, naturally, to fix the underlying table data.

'-999' used for all condition

I have a sample of a stored procedure like this (from my previous working experience):
Select * from table where (id=#id or id='-999')
Based on my understanding on this query, the '-999' is used to avoid exception when no value is transferred from users. So far in my research, I have not found its usage on the internet and other company implementations.
#id is transferred from user.
Any help will be appreciated in providing some links related to it.
I'd like to add my two guesses on this, although please note that to my disadvantage, I'm one of the very youngest in the field, so this is not coming from that much of history or experience.
Also, please note that for any reason anybody provides you, you might not be able to confirm it 100%. Your oven might just not have any leftover evidence in and of itself.
Now, per another question I read before, extreme integers were used in some systems to denote missing values, since text and NULL weren't options at those systems. Say I'm looking for ID#84, and I cannot find it in the table:
Not Found Is Unlikely:
Perhaps in some systems it's far more likely that a record exists with a missing/incorrect ID, than to not be existing at all? Hence, when no match is found, designers preferred all records without valid IDs to be returned?
This however has a few problems. First, depending on the design, user might not recognize the results are a set of records with missing IDs, especially if only one was returned. Second, current query poses a problem as it will always return the missing ID records in addition to the normal matches. Perhaps they relied on ORDERing to ease readability?
Exception Above SQL:
AFAIK, SQL is fine with a zero-row result, but maybe whatever thing that calls/used to call it wasn't as robust, and something goes wrong (hard exception, soft UI bug, etc.) when zero rows are returned? Perhaps then, this ID represented a dummy row (e.g. blanks and zeroes) to keep things running.
Then again, this also suffers from the same arguments above regarding "record is always outputted" and ORDER, with the added possibility that the SQL-caller might have dedicated logic to when the -999 record is the only record returned, which I doubt was the most practical approach even in whatever era this was done at.
... the more I type, the more I think this is the oven, and only the great grandmother can explain this to us.
If you want to avoid exception when no value transferred from user, in your stored procedure declare parameter as null. Like #id int = null
for instance :
CREATE PROCEDURE [dbo].[TableCheck]
#id int = null
AS
BEGIN
Select * from table where (id=#id)
END
Now you can execute it in either ways :
exec [dbo].[TableCheck] 2 or exec [dbo].[TableCheck]
Remember, it's a separate thing if you want to return whole table when your input parameter is null.
To answer your id = -999 condition, I tried it your way. It doesn't prevent any exception

Error Handling in Queries of Access #Error

I am working on a Attendance table in Access, where I have InTime and OutTime. These fields are of Date/Time Field.
Some records contains only Time like 11:40:00, some contain Date as well as time like 21-07-2015 11:45:00. Hence have used the below code for getting hours worked.
HrsPresent: Round(DateDiff("n",TimeValue(TimeSerial(Hour([TimeIn]),Minute([TimeIn]),Second([TimeIn]))),TimeValue(TimeSerial(Hour([TimeOut]),Minute([TimeOut]),Second([TimeOut]))))/60,2)
Using this above code, in a Column in making query gives correct Number of hours worked, but if any of the field is blank, i get #error in result.
I have tried using Nz , IsError, IsNumeric but all in Vain.
What is it that, I am doing wrong?
Is other way of getting hours worked?
You basically just need to make sure that both of the needed fields aren't blank before performing your calculation. You could do this using two IIF statements. If one field is blank then you simply assign a default value or handle it how you want.
In my example the default is zero, I have to warn you though this was done free hand and I am not super confident that my brackets line up properly. Also I am sorry that it is all on one line, I couldn't think of a logical way to break it down.
HrsPresent: IIF(Nz([TimeIn],"") = "", 0, IIF(Nz([TimeOut],"") = "", 0, Round(DateDiff("n",TimeValue(TimeSerial(Hour([TimeIn]),Minute([TimeIn]),Second([TimeIn]))),TimeValue(TimeSerial(Hour([TimeOut]),Minute([TimeOut]),Second([TimeOut]))))/60,2)))
For more information on IIF statements you can use visit here: http://www.techonthenet.com/access/functions/advanced/iif.php

IIf Statement only manipulating part of the data in a field

I created an IIf statement in a MS Access query, to fill null spaces in a particular field. The statement in only affecting some of the data, but not all. Why would it only work on a certain percentage of the records?
Field:Line_off_Date
Table:Claims
Criteria:IIf(IsNull("Line_off_Date "),"1/1/1900"
Here is the official Sql after delimiting:
SELECT Claims.Line_off_Date
FROM Claims
WHERE (((Claims.Line_off_Date)=IIf("Line_off_Date IsNull",#1/1/1900#,"Line_off_Date ")));
I can't screen shot onto this site, but I could give a mock up representation:
Line_off_Date
12/23/2013
12/23/2013
5/16/2010
1/1/1900
1/1/1900
12/10/2000
11/4/2008
This is listed as a column, with a space between 1/1/1900 and 12/10/2000. When I post it here, it turns into a paragraph. I hope this helps in some way...
I'm unsure about your goal, but this looks like something where you could use the Nz Function.
Criteria: Nz(Line_off_Date, "1/1/1900")
If you want IIf instead, try it this way ...
Criteria: IIf(Line_off_Date Is Null, "1/1/1900", Line_off_Date)
Note those suggestions assume Line_off_Date is text datatype. If it is actually Date/Time, delimit the value with # instead of quotes.
Criteria: Nz(Line_off_Date, #1/1/1900#)
Criteria: IIf(Line_off_Date Is Null, #1/1/1900#, Line_off_Date)
I'm more confused after seeing your WHERE clause ...
WHERE (((Claims.Line_off_Date)=IIf("Line_off_Date IsNull",#1/1/1900#,"Line_off_Date ")));
Aside from the issues of quoting and so forth, I think the logic is faulty. If you say "show me rows where Line_off_Date = something other than what is stored in Line_off_Date", you may not get any rows back.
I think you need a different approach. If you need more help, show us a brief set of sample data and your desired output based on those data.
Based on the comment discussion, my understanding is you don't really want to filter the result set based on Line_off_Date --- which means this is not a WHERE clause issue. Instead, you want to retrieve Line_off_Date values, but substitute #1900-1-1# for any which are Null. If that is correct, do the transformation with a field expression in the SELECT clause.
SELECT Nz(Claims.Line_off_Date, #1900-1-1-#) AS Line_off_Date_adjusted
FROM Claims;

Weird OpenEdge query behaviour

We have recently had to do some work with an OpenEdge database that a third party product uses, and today (after much hair-pulling), we finally identified why a view was returning no results.
This view in question combines about 100 separate tables, and is then queried against (we have limited rights to this database). One of the fields returned by this view is a hard-coded string literal, along the lines of
'John Smith' AS TheName
We were having difficulty running queries that included this string, which we were trying to RTrim (the view returned a lot of trailing spaces) and then concatenate with another field.
However, if we used RTrim on this field then, instead of returning an error message, or a null or something like that, the row simply wasn't returned. We weren't trying to use it in a WHERE clause or JOIN, this was simply part of the SELECT ... FROM VIEWNAME. After reviewing the view, it seemed that the view had erroneously detected the length of the string as 9 characters (no length was specified in the definition), and RTrim just didn't work.
Now, I could understand why this might lead to an error message, or a NULL value in the SELECT, but why would the row simply not be returned at all? This doesn't seem like good SQL behaviour and I've never seen it happen with any other RDBMS.
Other info : we're test querying via ODBC and WinSQL, with a view to this being included in an existing ASP.NET app. We don't have access to the backend except via this, although we do have rights to create views.
Update : As a freaky follow-up, we have now discovered that if we attempt to query this view without any WHERE clause, no records are returned. This may have the same cause.
This sounds like it could be related to the SQL-WIDTH within the progress database. One problem with Progress is that if the content of the field exceeds the SQL-WIDTH then you will get strange SQL behaviour (sometimes the driver might fail, other times you get no results).
To identify this you need to use the dbtool command to check for SQL-WIDTH's that may be exceeded.
Make sure you don't have blanks. Trimming doesn't remove blanks only spaces. Blanks are also not nulls. There is a difference in the character set while it is not visibly different in your editor.
I have run into this with a few databases, DBII, Oracle, PostGreSQL. Check the character set of your editor and try viewing the tables, you might see nothing or you might see big rectangles.
That sounds like very strange behavior. Just code around it, do the trim and/or string manipulation in the application and go on your way.