Access 2016 - Linked Excel Tbl made into Qry - get Data type Mismatch when trying Unmatched - sql

This seems like a very simple question, however, I am still not getting rid of the Data Type Mismatch. Scenario:
-> Excel File link in as table [tbl_Mast_CC_List], I convert the possible Cost Center Numbers into Values for safety via query, there are NO text variables in the Cost Center or preceding 000's, next arrow
-> qry_CC_Clean is CostCenter:Val([tbl_Mast_CC_List.CostCenter])
-> then I create the Unmatched Query, here is the SQL:
SELECT
qry_CC_S1_Clean_F2F_Alloc.DataName
, qry_CC_S1_Clean_F2F_Alloc.Year
, qry_CC_S1_Clean_F2F_Alloc.CostCenter
FROM qry_CC_S1_Clean_F2F_Alloc
LEFT JOIN qry_CC_S1_Clean_Mast_CC_List
ON qry_CC_S1_Clean_F2F_Alloc.CostCenter = qry_CC_S1_Clean_Mast_CC_List.CostCenter
WHERE (((qry_CC_S1_Clean_Mast_CC_List.CostCenter) Is Null))
ORDER BY qry_CC_S1_Clean_F2F_Alloc.CostCenter;
The only time I can get it to work is if I make table of the query and I don't really want to do that. Any suggestions would be greatly appreciated because I have to run this unmatched query against numerous tables to make sure the company is not missing any cost centers rolling through. Thank you!

Your problem is likely due to using the val() function and trying to test it against nulls. My understanding is that val() doesn't return nulls, it returns 0 when it can't find anything. You might be better off running the conversion in the opposite direction, i.e. using CStr() on the numeric CostCenter field and comparing that to the text data from Excel.
Alternately you could change the Excel field itself to a number format instead of text.

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.

MS Access Having Clause

Alright so I understand the point of the HAVING clause. I am having an issue and I am wondering if I can solve this the way I want to.
I want to execute one query using ADODB.Recordset and then use the Filter function to sift through the data set.
The problem is the query at the moment which looks like this:
SELECT tblMT.Folder, tblMT.MTDATE, tblMT.Cust, Sum(tblMT.Hours)
FROM tblMT
GROUP BY tblMT.Folder, tblMT.MTDATE, tblMT.Cust
HAVING tblMT.Cust LIKE "TEST*" AND Min(tblMT.MTDATE)>=Date()-30 AND MAX(tblMT.MTDATE)<=Date()
ORDER BY tblMT.TheDATE DESC;
So the above works as expected.... however I want to be able to use the tblMT.Cust as the filter without having to keep re querying the database. If I remove it I get a:
Data type mismatch in criteria expression.
Is what I am trying to do possible? If someone can point me in the right direction here would be great.
Ok... the type mismatch is caused because either tblmt.mtdate isn't a date field or tblmt.hours isn't a number field AND you have data that either isn't a date or isn't a number when the customer isn't like 'TEST*'. Or, for some customers, you have a NULL in mt.date and null can't be compared with >=. you'd still get the error if you said where tblMt.cust not like "TEST*" too.
Problem is likely with the data or your expectation and you need to handle it.
What data types are tblMT.hours and tblMt.MtDate?

SQL Server function returns different results in two different query panes

Got me flummoxed!: I have a function that I call...
SELECT UNIT
FROM POWER_ASSETS.[dbo].[returnbaseload] ('03-12-2015','EUR')
WHERE C_TIC = 'LSE:SOE'
The function "returnbaseload" queries values from a view and does some calcs with the values. Simple. It returns 29 rows.
If I open it up in a new SQL query tab, copy n paste... it returns 533 rows.
If I copy and paste from new tab back to old tab.... 29 rows.
Any ideas? Got me beat.
P.S have also tried putting
Use POWER_ASSETS
GO
just in case there was a duplicate table accidentally created somewhere in the master...
I am worried because I am calling the function eventually from a vb program and am getting the wrong amount of rows from the sql query in vb. That's what got me investigating... the right amount of rows was from the new tab, 533 rows.
There's no way a deterministic select fetches different result sets when using the same parameters. Period.
As comments indicates you must being overloking or missing something.
1 - Be sure both panes are using the same.
[SERVER/INSTANCE].[DATABASE].[SCHEMMA].[TABLE]
it's by far the most common scenario.
It also is valid for function/SP calls. Be sure you are calling the same object and not a different version of it.
2 - Be sure both are using the same user/privileges.
Maybe you are using different connection parameters
.
3 - Be sure there's no implicit convertion messing with your query.
You are using some sort of varchar to date convertion here. Be sure you got the same settings (collation, copy from a unicode to a UTF-8 archive, etc.) in both tabs. Also you can try to query the table using some sort of GETDATE() function instead of dealing with that varchar literal.
4 - Be sure your data is not changing while you query it.
Stop the server and put it in single user. Maybe your data is just being updated.
5 - Be sure there are not any random function in the query.
Sometimes we got funny BL and someone unintented put some rand logic in it.
6 - Be sure you are not just drunk or tired.
Once I and a friend where working for like +20hrs no stop. He got angry with a buggy "dot" in the screen. Turned ou it was a actual bug (a fly) and also tried to get rid of it with the mouse pointer.
Calm down and call a friend to get a look on it.

Convert table data into flat format using of Excel VBA

I have the following input data range
and the following desired output
The first block with Compals will be always the same - so 5 rows. Base Unit Current and Base Unit Later blocks will be variable - sometimes eight options and sometimes more than eight options.
I'm very new in excel vba so unfortunately I have no idea how to do that. Please, could anyone help me or give me some advice. Many thanks in advance.
Wonder you accept this kind of answer of not?
Instead of table, I think this kind of pivot may suitable your need:
I reform the table
Create the pivot table

Invalid character value for cast specification (#0) - I know the problem, but not how to resolve it

I'm having a problem with a button in MS Access querying a SQL View that doesn't have a foreign key.
My question is VERY similar to the question found here: MS Access error "ODBC--call failed. Invalid character value for cast specification (#0)" -- That seems to be my exact problem, but I'm not sure how to resolve it. Here are some more details. First, the exact error message:
ODBC--call failed.
[Microsoft][ODBC SQL Server Driver]Invalid character value for cast specification (#0)
Here's where I differ. I have a button in MS Access that does the following:
Private Sub btnMachineCutSheet_Click()
Dim stDocName As String
stDocName = "qryCutSheetByMachines"
DoCmd.OpenQuery stDocName, acNormal, acEdit
End Sub
The query you see listed there (qryCutSheetByMachines) is a pretty long query, but I've narrowed the problem down to one line. Here's the query:
SELECT
vwCutSheet.Network,
vwCutSheet.NetworkSpeed,
vwCutSheet.Duplex
FROM vwCutSheet
INNER JOIN local_tblCreateCutSheet
ON vwCutSheet.EquipmentID = local_tblCreateCutSheet.EquipmentID;
Keep in mind that all the tables/views are linked tables from a MS SQL 2008 database
The first bit of oddness is that everything works just fine if I remove the vwCutSheet.NetworkSpeed, line. Unfortunately, I need that data.
Now, if I take out the JOIN statement the query works fine. Obviously I need the join or I wouldn't have it there. Now, the problem (I assume) is that the view (vwCutSheet) does not have a PK (should views have primary keys?). vwCutSheet.EquipmentID cannot be a PK though because there will usually always be a case of multiple EquipmentID's with the same value in this view.
And the last bit of information that might be messing things up is this. If I open up the view in Design view (in MS Access) I can see that Access is expecting a data type of "Number" - but if I look at the table that the view queries from originally, the data type is a varchar(5). I expect that Access is looking at the contents of the data and seeing nothing but numbers (values are 10,100,1000, and 10000).
I'm happy to say I didn't design this, so it's not my fault! Hah... but, I do have to support it, so it's up to me to make it work.
So... I think that's all the pertinent info. Let me know if you require more info and I'll edit my question as we go along.
Thanks in advance for any help!
EDIT: More info found:
The table that the view pulls from uses a column with a varchar(5) data type. The reason that field is a varchar(5) is because it's possible to specify a 'speed' of 10, 100, 1000, 10000, or Auto.
Additionaly, it is possible for the populated field in the view to be null.
Not sure if you have permission to work on the SQL side, but if so, try creating your join there and see if it has a problem.
Also, consider changing your stored value 'auto' to something numeric and invalid, like -1, again assuming you can make changes on the sql side.
You may need to do some limiting or conversion on a linked table you can't change before you can join. Instead of the one query you have, you may need 3, if you need to manipulate data in both linked sources before you can join them.
In response to your comment,
joining a table linked to SQL server and a local Access table should work, if the data types and values are compatible. If the linked table defined your key field as numeric, but contains text values, like 'auto', it can't work. You'll need to change the linked table to a text field instead of numeric so it can join with the text field in your local table.
I'd say you have a data error. You're storing numbers in a text field, except for when you don't.
If instead you'd define 0 as meaning "Auto" then you could make it a numeric field. Or, use a lookup table and a foreign key value so that 1=10, 2=100, 3=1000, 4=100000 and 0=Auto. If you do that you could use the value as exponent (10^N), and the results would be 1, 10, 100, 1000, 10000, where 1 would be your Auto value.
Or make NULL = Auto, in which case 10^Null would still give you Null (Auto), while all the other values would work.
This would completely design away the problem.
But it does assume you have access to the data table.
As an alternative if you can't change the field's data type, you could create a view that does one of the above for you. To me the easiest thing to do is get rid of the damned text value, "Auto". Of I were doing that, I'd likely convert "Auto" to Null so the result would be a column of numbers with Nulls.