Select with Contains parameter not working with null - sql-server

With my select below, if blank string is passed in I get the following error: Null or empty full-text predicate
in my DBAdapter when fetching rows from the database. If I provide a value, such as Well, I do not get results when I should as Well is in the r.[Desc] column. If I pass in Well One, I get: Syntax error near 'one' in the full-text search condition 'Well one'.
If I pass in One, I get nothing.
I've read similar questions here and have not seen a pattern where the value passed in can be nothing, the beginning of the column data, a word in the middle of the column data or more than one word in any order of the column data. I thought Contains returns the row if the column contains the value or part of the value passed in.
What am I doing wrong?
if #Drawing = ''
set #Drawing = null
if #ItemName = ''
set #ItemName = null
if #CF3 = ''
set #CF3 = null
if #Desc = ''
set #Desc = null
if #Design = ''
set #Design = null
if #MaxPSI = 0
set #MaxPSI = null
Select distinct
,r.[DRAWING]
,r.[DESC]
,r.[OP_PSI]
,r.[MAX_PSI]
,r.[MAX_TEMP]
,r.[Insulated]
,r.[DESIGN]
From Ref r
inner join Eng e on e.[DRAWING] = r.[DRAWING]
where r.SurveyNumber = #SurveyNumber
And (rtrim(#Drawing) is NUll or rtrim(r.DRAWING) like rtrim(#Drawing) + '%')
And (rtrim(#Design) is NUll or rtrim(r.DESIGN) like rtrim(#Design) + '%')
And (rtrim(#MaxPSI) is NUll or rtrim(r.MAX_PSI) like rtrim(#MaxPSI) + '%')
And (rtrim(#CF3) is NUll or rtrim(e.CF3) like rtrim(#CF3) + '%')
And (rtrim(#ItemName) is NUll or rtrim(e.ITEM_NAME) like rtrim(#ItemName) + '%')
AND ((#Desc = '""') OR CONTAINS( (r.[Desc]), #Desc))

I think you can try checking for empty as follows:
AND ((#Desc = '""' OR #Desc = '') OR CONTAINS( (r.[Desc]), #Desc))
I suspect the empty predicate may be getting passed as '' instead of "".
Have not used Contains much but from section in the doc [here][1] it seems you either need operators between the words or need to wrap expression in double quotes "". So what you can do is try passing params like this:
AND ((#Desc = '""' OR #Desc = '') OR CONTAINS( (r.[Desc]), '"'+#Desc+'"'))

What possible purpose is
rtrim(#Drawing) is NUll
If it is NULL the rtrim has no meaning. Besides comparison of string basically does an rtrim.

Related

Getting System.QueryException: line 1:40 no viable alternative at character '\'

Am using a dynamic query to get data. Below is my code
if(objVal != null){
sObject obj = Schema.getGlobalDescribe().get(objVal).newSObject();
if(ConditionVal== null || ConditionVal=='')
query = 'Select Id From '+objVal+ ' Limit 10000';
else{
ConditionVal= String.escapeSingleQuotes(ConditionVal);
query = 'Select Id From '+selectedObj+' WHERE '+ConditionVal+' LIMIT 10000';
}
List<SObject> objlst = Database.query(query);
Am getting "objVal" , "ConditionVal" value form VF page
Example objVal = 'Account' ConditionVal = 'industry = 'Apparel'
after executing the code am getting the query like this
Select Id From Account WHERE industry = \'Apparel\' LIMIT 10000
update the value of ConditionVal variable as below,
ConditionVal = 'Industry = \'Apparel\'';
the query will work as expected.

SQL: how to do an IF check for data range parameters

I am writing a stored procedure that takes in 4 parameters: confirmation_number, payment_amount, start_range, end_range.
The parameters are optional, so I am doing a check in this fashion for the confirmation_number, and the payment_amount parameters:
IF (#s_Confirmation_Number IS NOT NULL)
SET #SQL = #SQL + ' AND pd.TransactionNumber = #s_Confirmation_Number'
IF (#d_Payment_Amount IS NOT NULL)
SET #SQL = #SQL + ' AND pd.PaymentAmount = #d_Payment_Amount'
I would like to ask for help because I am not sure what is the best method to check for the date range parameters.
If someone could give me en example, or several on how this is best achieved it would be great.
Thank you in advance.
UPDATE - after receiving some great help -.
This is what I have so far, I am following scsimon recommendation, but I am not sure about the dates, I got the idea from another post I found and some playing around with it. Would you care looking at it and tell me what you all think?
Many thanks.
#s_Confirmation_Number NVARCHAR(50) = NULL
, #d_Payment_Amount DECIMAL(18, 2) = NULL
, #d_Start_Range DATE = NULL
, #d_End_Range DATE = NULL
...
....
WHERE
ph.SourceType = #s_Source_Type
AND ((pd.TransConfirmID = #s_Confirmation_Number) OR #s_Confirmation_Number IS NULL)
AND ((pd.PaymentAmount = #d_Payment_Amount) OR #d_Payment_Amount IS NULL)
AND (((NULLIF(#d_Start_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) >= #d_Start_Range)
AND ((NULLIF(#d_End_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) <= #d_End_Range))
(The parameter sourceType is a hard-coded value)
This is called a catch all or kitchen sink query. It is usually written as such:
create procedure myProc
(#Payment_Amount int = null
,#Confirmation_Number = null
,#start_range datetime
,#end_range datetime)
as
select ...
from ...
where
(pd.TransactionNumber = #Confirmation_Number or #Confirmation_Number is null)
and (pd.PaymentAmount = #Payment_Amount or #Payment_Amount is null)
The NULL on the two parameters gives them a default of NULL and makes them "optional". The WHERE clause evaluates this to only return rows where your user input matches the column value, or all rows when no user input was supplied (i.e. parameter IS NULL). You can use this with the date parameters as well. Just pay close attention to your parentheses. They matter a lot here because we are mixing and and or logic.
Aaron Bertrand has blogged extensively on this.
I do it like this
WHERE
COALESCE(#s_Confirmation_Number,pd.TransactionNumber) = pd.TransactionNumber AND
COALESCE(#d_Payment_Amount,pd.PaymentAmount) = pd.PaymentAmount
If we have a value for each of these parameters then it will check against the filter value otherwise it will always match the filter value if the parameter is null.
I've found that using COALESCE is faster and clearer than IF control statements or using OR in the WHERE clause.
There is another way.
But I tested and realized that a scsimon query is faster than mine.
AND (CASE
WHEN #Confirmation_Number is not null
THEN (CASE
WHEN pd.TransactionNumber = #Confirmation_Number
THEN 1
ELSE 0
END)
ELSE 1
END = 1)

Error converting data type nvarchar to numeric. Tried convert and replace

I am trying to add a sum of my forecast using a code
select
sum(cast(replace(replace(ZFREEGOOD, ',', ''), ' ', '') as decimal(22,8)))
from
TEMP_GBR_History_1611
I keep getting an error
Error converting data type nvarchar to numeric.
I used a case statement to figure out which rows failed. These are some of them
Would be of great help to get a solution
You're not handling the blank case, this works with test data:
select sum(cast(case when replace(replace(ZFREEGOOD,',',''),' ','') = '' then '0' else replace(replace(ZFREEGOOD,',',''),' ','') end as decimal(22,8))) from TEMP_GBR_History_1611
One option is to use try_convert(money,...) It tends to be a little more forgiving.
Example
Select AsMoney = try_convert(money,' 27,300') -- works!
,AsInt = try_convert(int,' 27,300')
,AsDec = try_convert(decimal(10,2),' 27,300')
,AsFloat = try_convert(float,' 27,300')
Returns
AsMoney AsInt AsDec AsFloat
27300.00 NULL NULL NULL

Simplifying a SQL Server query with a shortcut

I have a query where many columns could be blank or null. They actually have longer names than the example below which I am using as an example:
select *
from table1
where field1 is not null and field1 != '' and
field2 is not null and field2 != ''
...etc
It gets tiresome having to type
x is not null and x != ''.
Is there some way to specify "x is not null and x != ''"?
Like for Java with
StringUtils.isNotEmpty(x)
I use
where isnull(x, '') <> ''
a lot. I find it a bit easier to "understand" than nullif.
-- EDIT ---------------------------------------
I missed that they were all ANDed together. So, if all N fields must be non-null and not empty, assuming that all fields are strings (varchars), this should do it:
where isnull(field1 + field2 + field3 + ... + fieldN, '') <> ''
First, the strings are concatenated together:
If any are null, the result will be null
If none are null and all are empty, the result will be an empty string
Else, the result will be a non-empty string
Next, the results are isnulled:
If the concatenated value is null, it is set to an empty string
Else, you get the concatenated contents (empty or not-empty string)
Last, compare that with the empty string:
If True, then either all are empty or one or more is null
If False, none are null and at least one is not empty
Try
WHERE NULLIF(field1, '') IS NULL
For SQL Server, I would use COALESCE for this:
WHERE COALESCE(field1, '') > ''
ISNULL also works
If you want to exclude rows where every field is null or blank you can do it like this:
WHERE COAlESCE(Field1,Field2,Field3,Field4,Field5,'') <> ''

TSQL setting XML type as NULL if empty variable

I have a stored procedure that is relying on an IF #awardEmployees IS NOT NULL statement.
I have the variable defined at the top:
#awardEmployees XML = NULL
and then before the statement I am trying to set this:
SET #awardEmployees = NULLIF(#awardEmployees, '')
Which is returning the error:
The data types xml and varchar are incompatible in the equal to operator.
My code sends either an XML string or an empty string based on if anything was entered in the search field so I am trying to set it to NULL if it was empty.
Any other ways to accomplish this?
Use the exist exist() method - it will return 0, representing False, if it returns an empty result:
declare #awardEmployees XML = '<employees><employee><empID>1234</empID></employee></employees>'
IF #awardEmployees.exist('/employees/employee') > 0
BEGIN
print '#awardEmployees IS NOT NULL'
END
ELSE
BEGIN
print '#awardEmployees IS NULL'
END
declare #awardEmployees2 XML = ''
IF #awardEmployees2.exist('/employees/employee') > 0
BEGIN
print '#awardEmployees2 IS NOT NULL'
END
ELSE
BEGIN
print '#awardEmployees2 IS NULL'
END
See here.

Resources