I've been requested to migrate a project made with VBA in an Access DB to VB.Net with SQL Server 2008 R2. I've read in other threads that the function IIF does not come as a built-in function in such SQL Server version, creating it won't help it too, because the '=' operator can't be used to express a boolean in the first argument, and the problem using CASE is that some IIF's comes with more than one expression to evaluate inside.
In short words, this produces an error, "the = operator is not defined"
Iif(Value1 = Value2, 'Some return', 'Another return')
And an IIF expression like the following can't be translated to a CASE expression.
Iif((Value1 = Value2) And (Value3 = Value4), 'Value to return if true', 'Value to return if false')
I'm currently creating stored procedures and taking advantage of programming structures to overcome this problem, but it seems an inefficient workaround since there are lots of nested IIF's.
My question is, is there a more efficient way to do it?, or should i stick doing it with stored procedures?
Thanks in advance.
Both of your IIF calls can be converted to CASE expressions:
IIF(Value1 = Value2, 'Some return', 'Another return')
IIF((Value1 = Value2) AND (Value3 = Value4), 'Value to return if true', 'Value to return if false')
can be rewritten as
CASE WHEN Value1 = Value2 THEN 'Some return' ELSE 'Another return' END
and
CASE WHEN (Value1 = Value2) AND (Value3 = Value4)
THEN 'Value to return if true'
ELSE 'Value to return if false'
END
Related
In the table tblmap, I have columns mapelec, mappaper and mapplan. In these columns I have the words TRUE or FALSE. I am new to MySQL and have these T-SQL statements I am trying to convert to MYSQL statements:
IIf([tblmap].[mapelec],'Digital Maps'
IIf([tblmap].[mappaper],'Paper Maps','Other Maps')) AS MapType
To convert to MySQL I am guessing this is what it means:
CASE WHEN tblmap.mapelec = 'TRUE' THEN 'Digital Maps' WHEN tblmap.mappaper = 'TRUE' THEN 'Paper Maps' ELSE 'Other Maps' END AS MapType
Next:
IIf(([tblMap]![MapPlan]=True),'Plan View','') AS MapPlan
CASE WHEN tblmap.mapelec = 'FALSE' THEN 'Plan View' END AS MapPlan
Then this
IIf([tblmap].[mapelec],1)
IIf([tblmap].[mappaper],2,3)
CASE WHEN tblmap.mapelec = 'TRUE' THEN '1' END,
CASE WHEN tblmap.mappaper = 'TRUE' THEN '2' ELSE '3' END
I am making the assumption that [tblmap].[mapelec] is some kind of shorthand and means if the data in tblmap.mapelec evaluates as TRUE then do something. Can someone tell me if I am converting these correctly?
I was able to figure this out using my assumptions in my post.
IIf([tblmap].[mapelec],'Digital Maps'
IIf([tblmap].[mappaper],'Paper Maps','Other Maps')) AS MapType
Translated to
CASE
WHEN tblmap.mapelec = 'TRUE' THEN 'Digital Maps'
WHEN tblmap.mappaper = 'TRUE' THEN 'Paper Maps'
ELSE 'Other Maps'
END AS MapType
I made all my IIF statements follow this format and I eventually returned the same results as the original T-SQL statements.
I'm having problems translating the following CASE Statement on SELECT to SQLAlchemy ORM. I keep getting the error : "Ambiguous literal: False. Use the 'text()' function to indicate a SQL expression literal, or 'literal()' to indicate a bound value."
The Case statement checks a variable, and then either returns a column on the database or selects a literal. The literal is set prior to running the sql statement.
DECLARE #str_cntry_cd varchar(3)
SELECT COUNTRY_CD,
CASE WHEN #str_cntry_cd IS NOT NULL THEN RESOLUTION_ID
ELSE 10
END AS RESOLUTION_ID
FROM COUNTRY
The SQLAlchemy code looks as follows:
country_tbl = getattr(main_db.Base.classes, "COUNTRY")
c_res = case([(country_code != None, country_tbl.RESOLUTION_ID),],
else_ = literal(10)).label("resolution_id")
programs_sa = main_db.session.query(country_tbl.COUNTRY_CD.label("country_cd"),
c_res).all()
The table is as follows:
CREATE TABLE dbo.COUNTRY
(
COUNTRY_CD varchar(4) NOT NULL,
RESOLUTION_ID int NOT NULL
)
SQLAlchemy .9.9
Windows 7
SQL Server 2008 R2
Python 2.7
country_code != None is causing the problem.
That evaluates to python's True/False, which SQLAlchemy doesn't know how to convert to SQL's true/false as it is ambiguous. So you would need to either add the literal true/false for the SQL you are using, by using SQLAlchemy's text or literal functions. But a better way would be to use the true or false functions.
http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.true
http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.false
So you would replace the buggy section of the code with:
db.false() if country is None else db.true()
Hope this helps.
I have a field with below expression:
=join(iif(Parameters!FUP_Letter.Value = 1, "Yes", "No"), ", ")
When the report is loaded the field only says '#Error' instead of 'Yes, No', 'Yes' or 'No'
When I remove the IIF clause from this expression the result is just '1, 0' or '1' or '0'
As I am still new to SSRS I don't really know what I did wrong or how to find what I did wrong so if anyone could tell me the error or help me on my way I would be very grateful.
Kind regards
I suspect the error is being caused by you trying to join one value to nothing.
The IIF function isn't recursive, so it will return for the first value that you return so in the case above it will exit after evaluating 1 and returning yes. The join function then try's to join 'yes' to nothing and therefore errors.
you could do something like:
=Join(Replace(Replace(Parameters!FUP_Letter.Value,"1","Yes"),"0","No"), ",")
Actual used:
=Replace(Replace(join(Parameters!FUP_Letter.Value, ", "),"1","Yes"),"0","No")
I want to know the Select Query for MS Access with case sensitive.
I have two values for VitualMonitorName as below
VCode VirtualMonitorName
Row 1 (1, 'VM1');
Row 2 (2, 'Vm1');
Here both values are different.
If I write
"SELECT VCode FROM VirtualMaster WHERE VirtualMonitorName like '" + Vm1 + "'";
It replies VCode = 1 Only.
You can use the StrComp() function with vbBinaryCompare for a case-sensitive comparison. Here is an example from the Immediate window to show how StrComp() works. See the Access help topic for more details.
? StrComp("a", "A", vbBinaryCompare)
1
? StrComp("a", "A",vbTextCompare)
0
StrComp() returns 0 if the first two arguments evaluate as equal, 1 or -1 if they are unequal, and Null if either argument is Null.
To use the function in a query, supply the vbBinaryCompare constant's value (0) rather than its name.
SELECT VCode
FROM VirtualMaster
WHERE StrComp(VirtualMonitorName, "Vm1", 0) = 0;
This approach is also available to queries from other applications if they use the newer Access Database Engine ("ACE") drivers. For example, the following C# code
string myConnectionString =
#"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
#"Dbq=C:\Users\Public\Database1.accdb;";
using (OdbcConnection con = new OdbcConnection(myConnectionString))
{
con.Open();
using (var cmd = new OdbcCommand())
{
cmd.Connection = con;
cmd.CommandText =
"SELECT COUNT(*) AS n FROM [VirtualMaster] " +
"WHERE StrComp([VirtualMonitorName],?,?) = 0";
cmd.Parameters.AddWithValue("?", "Vm1");
cmd.Parameters.Add("?", OdbcType.Int);
var vbCompareOptions = new Dictionary<string, int>()
{
{"vbBinaryCompare", 0},
{"vbTextCompare", 1}
};
string currentOption = "";
currentOption = "vbBinaryCompare";
cmd.Parameters[1].Value = vbCompareOptions[currentOption];
Console.WriteLine(
"{0} found {1} record(s)",
currentOption,
Convert.ToInt32(cmd.ExecuteScalar()));
currentOption = "vbTextCompare";
cmd.Parameters[1].Value = vbCompareOptions[currentOption];
Console.WriteLine(
"{0} found {1} record(s)",
currentOption,
Convert.ToInt32(cmd.ExecuteScalar()));
}
}
produces
vbBinaryCompare found 1 record(s)
vbTextCompare found 2 record(s)
Check this out:
https://support.microsoft.com/kb/244693?wa=wsignin1.0
This article describes four methods of achieving a case-sensitive JOIN using the Microsoft Jet database engine. Each of these methods has advantages and disadvantages that should be weighed before choosing an implementation. The methods are:
StrComp
Case-Sensitive IISAM Driver
Hexadecimal Expansion
Binary Field
Using only built-in functions, add an additional custom column in the query design view:
location: InStr(1,[VCode],"VM1",0)
the zero parameter requests binary compare (case sensitive) when finding location of "VM1" within [VCode]
set the criteria in that column to >0 so only records with non-zero location in the vcode matching Like "*vm*" contain the exact VM1 string -
The WHERE clause looks like:
WHERE (((VirtualMaster.VCode) Like "\*vm*") AND ((InStr(1,[VCode],"VM1",0))>0));
Using at a simpler level of coding.
As a condition in a DCOUNT operation, checking on a Field (Column) that has to have the correct Case, and ignoring Blank States/Territories.
' lngcounter will count the all States
' or Territories Field ( Column) with this
' exact case value of 'Ohio'. ([ID] is an Autonumber ID field)
lngCounter = DCount("[id]", Trim(Me!tboDwellingTablename), "[State/territory],'Ohio',0) = 0")
This only does one letter:
MS-ACCESS SQL:
SELECT Asc(Left([Title],1)) AS t FROM Master WHERE (((Asc(Left([Title],1)))=105));
Title is the field you want to search
Master is the Table where Title field is located
105 Ascii code for character..
In this case only Title's that start with i not I
If you want to search for lower case "a" you would change the 105 to 97
I am trying to find the blank values and null values in a table. I am using Asc to assign the values of the table to a variable and then based on their ASCII values differentiating null and blank. But I am getting "runtime error 94: Invalid use of null" when the code tries to read the ASCII value of a null field.
When I have to deal with return values that can be either Null or zero-length string, I use a function that converts ZLS to Null:
Public Function varZLStoNull(varInput As Variant) As Variant
If Len(varInput) = 0 Then
varZLStoNull = Null
Else
varZLStoNull = varInput
End If
End Function
This takes advantage of the fact that the VBA Len() function treats a Null and a ZLS exactly the same so that you don't have to handle each case individually.
However, remember that if you use this in a WHERE clause, you'll be losing performance because it can't use the indexes. Thus, in a WHERE clause, you'd test for IS NULL or =""
SELECT MyField
FROM MyTable
WHERE MyField Is Null Or MyField = ""
That will be much more efficient. The varZLSToNull function is most useful when you're appending processed data to a field that has ZLS Allowed set to NO (as it should).
Another thing you should consider is changing your field so that it disallows ZLS, then running a query (using the WHERE clause above without the Is Null) to replace all the ZLS's with Nulls.
Of course, that assumes that your data is not distinguishing between Null and ZLS as meaning two different things (Null meaning "we haven't recorded any value here" and ZLS meaning "we have recorded an empty value here").
You can try the following user-defined function to test the table value:
Public Function text_test(str_in as Variant) As Long
' given input str_in, return -2 if input is Null,
' -1 if input is zero-length string; otherwise return 0
' use function Nz to test if input is Null and return -2,
' otherwise check non-null value with Len
' and return -1 if it is a 0-length string,
' otherwise return 0 for anything else
text_test = IIf(Nz([str_in], "null") = "null", -2, _
IIf(Len(str_in) = 0, -1, 0))
End Function
In the immediate window run a test with different inputs:
?text_test("fred");text_test("");text_test(Null);text_test(9);text_test(False)
Should return:
0 -1 -2 0 0
Note that you cannot use str_in as string in the function declaration since this will cause the same error you refer to in your question.
I think you should be using IsNull() to decide if a value is null.
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5034252.html
encapsulate your code inside a if statement and compare the string value to vbNullString like this:
If (Not (<string> = vbNullString) Then
if the string is NOT null execute your original code
if it is null add an Else block to execute what you need to do if the value is null
Yeah, it's an old thread, big deal...
This is the most concise way to test a value for Null and zero-length that I've seen:
FinalValue = IIf(Not Len(Nz(Value, "")) = 0, Value, Null)
How it might perform compared to David Fenton's excellent Function above, I do not know. I do know that the one-liner I present here and David's function do almost exactly the same thing. I suspect the one-liner might perform a bit better than a call out to a Function. On the other hand it makes use of an inclusive If, so it may in fact be slower. Who knows?
I use it in Class modules, mainly. For example, when creating a record with a DAO Recordset:
With rst
.AddNew
!JobCardID = IIf(Not m_JobCardID = 0, m_JobCardID, Null)
!ConstructionProjectID = IIf(Not m_ConstructionProjectID = 0, m_ConstructionProjectID, Null)
!MajorDisciplineID = IIf(Not m_MajorDisciplineID = 0, m_MajorDisciplineID, Null)
!ActivityDescriptorID = IIf(Not m_ActivityDescriptorID = 0, m_ActivityDescriptorID, Null)
!ActivityStatus = IIf(Not Len(Nz(m_ActivityStatus, "")) = 0, m_ActivityStatus, Null
'etc...
End With
In the above code, ActivityStatus is the relevant String.
Note: I never design a database with fields allowing zero-length strings. Repeat: NEVER.