Is it possible to make a NOT LIKE filter on the ExecSQL subject of a MAPITable? Outlook Redemption - outlook-addin

Is it possible to make a NOT LIKE filter on the ExecSQL subject of a MAPITable?
I'm doing this filter:
MAPITable mt = session.Stores.MAPITable;
mt.Item = inbox.Items;
var records = mt.ExecSQL($"select Subject, EntryID from Inbox Where Subject not like '%[DocSite %'");
But I'm having this exception:
An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in
ConsoleApplication1.exe
Additional information: Assertion failed: Number of fields == 1
If I remove the NOT constrain, the like filter it is apply and works. The problem is the NOT constrain.

Have you tried to put parenthesis around like the following and move the not operator out?
$"select Subject, EntryID from Inbox Where not (Subject like '%[DocSite %') "

Related

Data adapter troubles

When I run the code the line which filled my datatable says that there is no value given for one or more parameters
Order = New OleDb.OleDbDataAdapter("SELECT * FROM Orders WHERE
Driver_ID = " & ID, DBREF)
Order.Fill(dataODtable)
DGVorders.DataSource = dataODtable
The code says this:
An unhandled exception of type 'System.Data.OleDb.OleDbException'
occurred in System.Data.dll
Below is an image link to the database and table it is referencing.
(Database orders table)
If I try run the code without the where statement it runs without crashing.
The field DRIVER_ID is clearly a string, as such you need single quotes around the value you want to use for the WHERE clause.
But that would be wrong for a long list of reasons (Sql Injection, Parsing errors, automatic type conversion with incompatible locales).
So you really need to start using parameterized queries as soon as possible to avoid these misteps
Dim cmdText = "SELECT * FROM Orders WHERE Driver_ID = #drvID"
Order = New OleDb.OleDbDataAdapter(cmdText, DBREF)
Order.SelectCommand.Parameters.Add("#drvID", OleDbType.VarWChar).Value = ID
Order.Fill(dataODtable)
DGVorders.DataSource = dataODtable
Now the query is no more built concatenating together strings pieces (the main source for sql injection hacks) but you create a parameter object of the correct type and pass it to the database engine that will use it when needed.
Another benefit is the more clear code you get. In this case perhaps is not very evident but with more complex queries you will have a more clear understanding of what you are asking to do to the database.
You can try like this:
Order = New OleDb.OleDbDataAdapter("SELECT * FROM Orders WHERE
Driver_ID = '"& ID &"'", DBREF)
Order.Fill(dataODtable)
DGVorders.DataSource = dataODtable
maybe this will be the problem.
if Driver_ID is alphanumeric column, select query should be SELECT * FROM Orders WHERE Driver_ID = '" & ID & "' ;"

Dealing with LINQ to Objects when object not found

I am using Linq statement as per below to find student name by its ID. It works fine. However there are cases where there is no student with given ID. In those cases an error is thrown "Object reference not set to an instance of an object."
How to efficiently deal with this problem?
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007").Name
If you are satisfied with Name being null if there is no matching student, you can use the null conditional operator for member access:
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007")?.Name
As usually answer is "it depend" - it depend on how you will use result you will get
If you want get some "default"/empty string instead of name when collection doesn't contain item
Dim result = Students.Where(Function(student) student.ID = "NO00007").
Select(Function(student) student.Name).
DefaultIfEmpty(String.Empty).
First()
Almost same approach if you want to get some "empty" object instead of null
Dim resultStudent = Students.Where(Function(student) student.ID = "NO00007").
DefaultIfEmpty(New Student With { .Name = "empty" }).
First()
From performance point of view approach above are same as FirstOrDefault - but provide little bid better readability(subjective of course)

Use an Access Forms Unbound text box as a Field filter in a table

Access 2013 - Reference an Unbound text box on a Form
I am currently trying to use an unbound text box [Text161] on a Form name [DCM_Gap_Servers] to sort information through a table. I want the query that I created to be able to take the users input from [DCM_Gap_Servers]![Text161] as the field that is being sorted from the table names 'Server'.
This is the SQL I am using right now in the query:
SELECT * FROM Servers WHERE "Forms![DCM_Gap_Servers]![Text161]" IS NULL
** I have already Tried:
"Forms![DCM_Gap_Servers]![Text161]" ; (Forms![DCM_Gap_Servers]![Text161]); Forms.[DCM_Gap_Servers]![Text161]
This will work at any time if I replace the Text Box reference with the actual Field name I am using, but since there are hundreds of combinations of fields, I need the reference to work.
I have looked all over, and I can't seem to find the correct answer. I am willing to do it in VBA if needed, whatever it takes to get the filtering done correctly.
Thank You.
It is:
SELECT * FROM Servers WHERE Forms.[DCM_Gap_Servers].[Text161] IS NULL
but that will just select all records whenever your textbox is Null.
So it rather is:
SELECT * FROM Servers WHERE SomeField = Forms.[DCM_Gap_Servers].[Text161]
To use the form value as a field name, you must use concatenated SQL:
strSQL = "SELECT * FROM Servers WHERE " & Forms![DCM_Gap_Servers]![Text161].Value & " IS NULL"
This you might pass to the SQL property of an existing query object:
MyQueryDef.SQL = strSQL
Or:
Constant SQL As String = "SELECT * FROM Servers WHERE {0} IS NULL"
FieldName = Forms![DCM_Gap_Servers]![Text161].Value
MyQueryDef.SQL = Replace(strSQL, "{0}", FieldName)
Of course, take care the the field name isn't a zero length string.

Why is Access asking for a param arg here?

In order to test whether a particular query against an MS Access "database" should be returning any records (it's not), I am running it in Access like so:
SELECT TOP 5 t_accounts.account_no as AccountID, IIF(ISNULL(t_accounts.name),'[blank]',t_accounts.name) AS Name
FROM t_accounts
INNER JOIN td_department_accounts ON (t_accounts.account_no = td_department_accounts.account_no)
WHERE (AccountID >= 1) AND type = 'DE'
The "Top 5" and the "AccountID >= 1" are hardcoded versions of what I'm using in the code:
cmd.CommandText =
string.Format(
#"SELECT TOP {0} t_accounts.account_no as AccountID, IIF(ISNULL(t_accounts.name),'[blank]',t_accounts.name) AS Name
FROM t_accounts
INNER JOIN td_department_accounts ON (t_accounts.account_no = td_department_accounts.account_no)
WHERE (AccountID >= #firstId) AND type = 'DE'", CountToFetch);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#firstId", FirstId);
Yet Access prompts me with:
(If I enter "1", it does then return a few records).
What must I do to get Access' query running process to straighten up and fly right? Or is it me that has vertigo?
UPDATE
Perhaps a clue is that with the C# code shown above, I get, "No value given for one or more required parameters." Why? The only parameter is firstId, and it's value is indeed supplied...?!?
UPDATE 2
Even though it works, running Code Analysis on it causes that august tool to wrinkle its brow, scowl, and growl:
CA2100 Review SQL queries for security vulnerabilities The query
string passed to 'OleDbCommand.CommandText.set(string)' in
'NRBQSQLRepository.GetNDepartmentsFromID(string, int)' could contain
the following variables 'CountToFetch'. If any of these variables
could come from user input, consider using a stored procedure or a
parameterized SQL query instead of building the query with string
concatenations.
From Why does Access want me to enter a parameter value?
Access displays the Enter Parameter Value dialog box when you open an
object that contains an identifier or expression that Access cannot
interpret.
In this case AccountID is the field alias for t_accounts.account_no. You tried to reference the field alias in the Where clause. You can't do that.
change
WHERE (AccountID >= 1) AND type = 'DE'
to
WHERE (t_accounts.account_no>= 1) AND type = 'DE'

Run time error 3021- no current record

I want to link the result of a query to a Textbox but I get this error: here is my code:
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT XValue, YValue,Wert FROM tb_DCM_Daten WHERE (FzgID=" & Forms!frm_fahrzeug!ID & " AND Name='" & List2.Value & "')")
Text10.Text = rst!XValue //error in this line
It should be return c.a 20 record
Why do I get this error and how can I solve it?
One possible reason for the error is that Name is a reserved word in Access, so you should use
... & " AND [Name]='" & ...
You could also test for rst.EOF before trying to use rst!XValue. That is, to verify whether or not your query is returning at least one row you can add the code
If rst.EOF Then
MsgBox "The Recordset is empty."
End If
immediately after the .OpenRecordset call. If the Recordset is empty, then you'll need to verify your SQL statement as described by #GregHNZ in his comment above.
Usually, I would do this. Create a new query in Access , switch to SQL View , Paste my code there and go to Design >> Run.
SELECT XValue, YValue,Wert FROM [tb_DCM_Daten] WHERE [FzgID]=12 AND [Name]='ABC';
if your query syntax is correct you should see the result otherwise error mssg will tell where you are wrong. I used to debug a much more complicated query than yours and this is the way that I've done.
If there is still error, maybe you should try
Dim sql as String
sql = "SELECT...."
Set rst = CurrentDb.OpenRecordset(sql)
Another possible reason might be your table name. I just wonder what is your table name exactly ? if your table contains white space you should make it like this [DCM Daten].
One more thing I like to add that may cause this, is your returning a sets of resultset that has "Reserved word" fields, for example:
Your "Customers" table has field name like the following:
Custnum | Date | Custname
we know that Date field is a reserved word for most database
so when you get the records using
SELECT * FROM Customers
this will possible return "No Current Record", so instead selecting all fields for that table, just minimize your field selection like this:
SELECT custnum, custname FROM Customers
After trying the solutions above to no avail, I found another solution: Yes/No fields in Access tables cannot be Null (See allenbrowne.com/bug-14)
Although my situation was slightly different in that I only got the "No current record." error when running my query using GROUPBY, my query worked after temporary eliminating the Yes/No field.
However, my Yes/No field surprisingly did not contain any Nulls. But, troubleshooting led me to find an associated error that was indeed populating my query result with Null Yes/No values. Fixing that associated error eliminated the Null Yes/No values in my results, thus eliminating this error.
I got the same error in the following situation:
In my case the recordset returned one record including some fields with Null value.
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT * FROM tbl WHERE (criteria)", dbOpenDynaset)
Textbox1 = rst!field1 'error in this line - Non-Null value
Textbox2 = rst!field2 'Null value
Textbox3 = rst!field1 'Null value
Viewing Locals when rst is opened and before asignments, shows the recordset as I expect it to be. The error is thrown when trying to a asign a value from this recordset.
What fixed this, is ensuring that all fields contained non-Null values.
Just posting this for future seekers.