VBA in query error evaluating false part of IIF - vba

I have the following column in a query.
iif(Len([Field1])=0,0,Asc(Mid([Field1] & "",Len([Field1]))))
The idea is that it should return the ASCII value of the last character in a string field.
The problem is that if Field1 is blank the statement errors with the following message: "Invalid procedure call or argument (Error 5)". If the field is blank it should return 0.

Assuming blank means either Null or an empty string, you can concatenate an empty string to [Field1], and if the combined length is 0, return 0.
The Right() function is more direct than Mid() to get the last character.
SELECT IIf(Len([Field1] & "")=0,0,Asc(Right([Field1],1)))
FROM YourTable;

By all means you have HansUp's answer to go ahead. :)
..At any point of this querying voyage, your query with IIF gets very very long... ;) here a head start with a UDfunction that uses REGEX. In your case the most important aspect is to validate the input - not much of getting the ASCII value. Since your concern mainly on last character, what if your Field1 contains alphanumeric value and if your last character happens to be digit, special character instead of String. Well, just to be safe, we could validate that in the following funciton which will respond only to Strings. Another advantage is that you can re-use this function within your db.
Perhaps this really is complicating your process :D
Option Compare Database
Option Explicit
Public Function GetASCII(strField1 As String) As Integer
Dim regex As Object
Dim strTemp As String
Set regex = CreateObject("vbscript.regexp")
'--assume strField1 = "hola", you may enter different types
'-- of values to test e.g. "hola1, hola$ , hola;
With regex
.IgnoreCase = True
.Global = True
.Pattern = "[a-zA-Z]+"
'--check for null
Select Case IsNull(strField1) '-- validates any other datatype than String
Case True
GetASCII = 0
Case Else
Select Case IsError(strField1)
Case True
GetASCII = 0
Case Else
Select Case IsEmpty(strField1)
Case True
GetASCII = 0
'--check if entire string is String
'--only (no special characters, digits)
'--you may change this to only check the
'----last character if your Field1 is alphanumeric
Case Else
Select Case .Test(strField1)
Case True
strTemp = Mid(strField1, Len(strField1), 1)
GetASCII = Asc(strTemp)
Case Else
GetASCII = 0
End Select
End Select
End Select
End Select
End With
Set regex = Nothing
End Function
Note: Thought this would be helpful in the long run :) An Access Query Primer Article.

Related

TSQL Format SSN/TIN (SQL Server 2016+)

I need to format US SSN/TIN strings with dashes when they appear to be valid
(where valid = 9 digits) and otherwise return what is in the field (with leading 0s).
123456789 should format to 123-45-6789
and 3456789 formats to 003-45-6789
Can someone tell me why this code doesn't work?
Declare #TaxIDNum VarChar(11)
Set #TaxIDNum = '3456789'
Set #TaxIDNum = Right('0000'+#TaxIDNum,9)
Set #TaxIDNum =
CASE #TaxIDNum WHEN Len(#TaxIDNum)=9 THEN
CASE #TaxIDNum
WHEN IsNumeric(#TaxIDNum)
THEN Left(#TaxIDNum,3)+'-'+Right(Left(#TaxIDNum,5),2)+'-'+Right(#TaxIDNum,4)
ELSE #TaxIDNum END -- return existing value
ELSE #TaxIDNum END -- return existing value
select #TaxIDNum, len(#TaxIDNum) as Length
I get a red squiggly error on the equals in "=9":
(Error text is: "Incorrect syntax near '='.")
Any solution that both works with a select or set, and solves the problem is welcome.
Thanks to #Larnu for mentioning Set #TaxIDNum=FORMAT(CONVERT(int,#TaxIDNum),'000-00-0000')
If I had error handling (our SSvr install doesn't) I would use Format. However if there is bad data, it breaks my query in a way from which I cannot recover.
Set #TaxIDNum=Replace('123-45-6789','-','') does avoid errors if the only data problem is that some of the rows are already formatted.
Seems like you could use FORMAT:
SELECT FORMAT(CONVERT(int,#TaxIDNum),'000-00-0000');
Why it does not work
From comments by [HABO][1]
You have mixed simple and searched case syntaxes, hence the complaint.
You should use LIKE (learn.microsoft.com/en-us/sql/t-sql/language-elements/…)
with a suitable pattern, e.g.
'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]', to determine if the
string contains only nine numeric characters.
So I tried this, which also didn't work:
SET #TaxIDNum =
CASE #TaxIDNum Like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
WHEN true
THEN …
HABO:
You've hit an fiendish edge case.
There is a boolean data type (with
values TRUE, FALSE and UNKNOWN), but you cannot get a firm grip on
one:
"Unlike other SQL Server data types, a Boolean data type cannot
be specified as the data type of a table column or variable, and
cannot be returned in a result set."
You can't have CASE «boolean-expression» WHEN true THEN «result» END
Solution:
Use LIKE leaving the CASE expression empty
declare #TaxIDNum VarChar(11)
set #TaxIDNum='3456789'
set #TaxIDNum=right('0000'+#TaxIDNum,9)
select #TaxIDNum
SET #TaxIDNum = CASE
WHEN #TaxIDNum Like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
THEN Left(#TaxIDNum,3)+'-'+SubString(#TaxIDNum,4,2)+'-'+Right(#TaxIDNum,4)
ELSE #TaxIDNum END
select #TaxIDNum

Oracle INSTR Function False Result

I'm trying to set an HTML format if the substring is within the string using the INSTR function and it worked fine in this case.
CASE WHEN INSTR({custcol_customer_price_group},{custcol_pricing_group}) >0
AND {custcol_line_number} is not null
THEN '<font size="2" color="Green"><b></b></font>'
WHEN {custcol_line_number} is null
THEN ''
ELSE '<font size="2" color="Red"><b>Pricing Group Not Defined</b></font>' END
but now I'm trying to set the checkbox marked if the substring is not within the string and am using the function but it doesn't work
INSTR({custcol_customer_price_group},{custcol_pricing_group}) !=0
also I tried this function
INSTR({custcol_customer_price_group},{custcol_pricing_group}) <>0
Unless I misunderstood what you are saying, you should check whether INSTR result is equal to 0 - it means that the searched string doesn't exist in the source.
In other words: you said
if the substring is within the string using the INSTR function and it worked fine in this case.
and used
INSTR({custcol_customer_price_group},{custcol_pricing_group}) > 0
Now, you're saying:
if the substring not with the string
and used
INSTR({custcol_customer_price_group},{custcol_pricing_group}) != 0
--
Wrong! Should be = 0

CASE statement where conditional includes an IN statement redshift

CASE
WHEN code IN ('FJS354', 'JDF334')
THEN 'Lower_form'
ELSE 0
END AS format
This returns an error in Redshift
invalid input syntax for integer: "Lower_form"
I know if I change 'Lower_form' to an integer it will work however I want this column to be a string. Is there a way to do this?
I want this column to be a string.
All branches of a case expression must return the same datatype. You are giving two literal values whose datatype is not the same (string vs integer): the database makes the decision to turn them both to integers - which is not what you want.
Rremove the ambiguity by being explicit about the datatype you want to return. That is, make this literal 0 a string:
CASE WHEN code in ('FJS354','JDF334')
THEN 'Lower_form'
ELSE '0'
END as format

How to detect a number and split in MS Access?

I cannot control these circumstances at the moment so please bear with me.
I pull email addresses from a field called EMAIL_O, and sometimes they are completely valid (somename#domain.com) and other times they have a 12-character phone number appended at the front (123-456-7890somename#domain.com).
How can I, in MS Access, detect which type of field I am seeing and remove the phone number appropriately when pulling in this data? I cannot just take the mid() from the 13th character because if the email is valid, I'd be removing good characters.
So somehow I need to detect the presence of a number and then apply the mid(), or just take the full field if no number is present.
Use pattern matching to check whether EMAIL_O starts with a phone number.
EMAIL_O = "123-456-7890somename#domain.com"
? EMAIL_O Like "###-###-####*"
True
EMAIL_O = "somename#domain.com"
? EMAIL_O Like "###-###-####*"
False
So you can use that strategy in an IIf expression. Apply Mid when EMAIL_O matches the pattern. Otherwise, just return EMAIL_O unaltered.
? IIf(EMAIL_O Like "###-###-####*", Mid(EMAIL_O, 13), EMAIL_O)
somename#domain.com
Those were examples copied from the Immediate window. If you want to use the same approach in a query ...
SELECT IIf(EMAIL_O Like "###-###-####*", Mid(EMAIL_O, 13), EMAIL_O) AS email
FROM YourTable;
Using the Left and IsNumeric functions you can just check to see if the first character is numeric, something like that is below. (Untested code).
Public Function CheckEmail(strEmail As String)
If IsNumeric(Left(strEmail, 1)) Then
strEmail = Right(strEmail, Len(strEmail - 13))
CheckEmail = strEmail
Else
CheckEmail = strEmail
End If
End Function
You can use regular expressions to get this done. Assume the number format in front of the email has a dynamic length you would not be able to start from 13th char as you suggested. Try pattern matching and replacing using RegEx. This would eliminate the entire string finding/cutting/joining operations
Try this:
Public Function FN_GET_EMAIL(iEmail As String) As String
Const mPattern As String = "^[0-9_-]+[0-9_-]"
With CreateObject("vbscript.RegExp")
.Pattern = mPattern
.Global = True
FN_GET_EMAIL = Nz(.Replace(iEmail, ""), "")
End With
End Function
sample results:
?FN_GET_EMAIL("123123123-123123123123-1231231231231EmailWith1123123Number#domain.com")
EmailWith1123123Number#domain.com
?fn_get_email("123-456-7890somename#domain.com")
somename#domain.com
in addition you can add a proper email validation or even change the pattern as per your needs without doing a complex string operation.
You could check for a numeric header:
If IsNumeric(Replace(Left(Nz([Email]), 12), "-", "")) Then
' chop 12 chars
Else
' use as is
End If

Set blank result equal to specific string in SQL Server

I have a query that returns a result set which contains a certain column that needs some tweaking. Basically, in the result set, there are certain rows that contain a blank value for the applicable column. What I need to do is set all instances of that blank value to a specific string. I have tried declaring a variable and setting the variable equal to the column name (using a SELECT statement) and then using an IF statement to set the value to a specific string if it is blank (' '). My code thus far is as follows:
declare #sourceNode varchar(30)
set #sourceNode = (select sn_name from pt_cust)
if #sourceNode = '' begin
set #sourceNode = 'None'
end
This code returns an error stating that the sub-query returns more than 1 value. This seems like an easy task but I am stuck at the moment. How can this be accomplished?
This is a case (heh) for CASE:
SELECT CASE WHEN sn_name = '' THEN 'None' ELSE sn_name END
FROM pt_cust
You are getting the error message you mentioned because your SELECT statement can return more than one row, in which case it can not be assigned to a variable.