The following SQL should demonstrate what I am trying to do. Unfortunately, when I try to run it, I get an error saying "Null or empty full-text predicate".
DECLARE
#essaySearchTerm varchar(100),
#game_id varchar(100)
SET #essaySearchTerm = NULL;
SET #game_id = 2;
SELECT * FROM tblImageInfo i
WHERE i.game_id = #game_id
AND (#essaySearchTerm IS NULL OR CONTAINS(i.essay, #essaySearchTerm))
What does this error mean?
How can I fix this?
This is because SQL Server operators are not guaranteed to be short-circuited, so if you have an expression 'A OR B', sometimes both A and B will be evaluated regardless of logical value of A. See this post or this one for more details.
In your case, when #essaySearchTerm is null, it tries to evaluate CONTAINS(i.essay, NULL), which is illegal. After changing your code to:
IF ISNULL(#essaySearchTerm, '') = ''
SET #essaySearchTerm = '""';
SELECT * FROM tblImageInfo i
WHERE i.game_id = #game_id
AND (#essaySearchTerm = '""' OR CONTAINS(i.essay, #essaySearchTerm))
the right side of the OR will be a legal expression, as CONTAINS(x, '""') returns an empty set.
Set the value of #essaySearchTerm to "" (two double quotes) if its null or empty:
if #essaySearchTerm is null
set #essaySearchTerm='""';
Related
Here is the code:
WHERE 1=1
AND TU.Auction_I IN (41, 42)
AND #StatePickupID = CASE
WHEN #StatePickupID IS NOT NULL
THEN (UP.TransportStateID = #StatePickupID)
END
AND #StateDropoffID = CASE
WHEN #StateDropoffID IS NOT NULL
THEN (UD.TransportStateID = #StateDropoffID)
END
So I only want to return records where UP.TransportStateID is equal to StatePickupID if it is not null, same thing for DropoffID. But I get a syntax error message where the equals sign is and I cannot find any other way to check for equality online. Any help or advice would be much appreciated.
I only want to return records where UP.TransportStateID is equal to StatePickupID if it is not null
This would translate as the following predicate:
#StatePickupID IS NULL OR #StatePickupID = UP.TransportStateID
When the parameter is not null, the predicate filters on TransportStateID; when the parameter is null, the filter is a no-op.
In your where clause, for both parameters :
WHERE 1 = 1
AND TU.Auction_I IN (41, 42)
AND ( #StatePickupID IS NULL OR #StatePickupID = UP.TransportStateID )
AND ( #StateDropoffID IS NULL OR #StateDropoffID = UD.TransportStateID )
I am trying to get the correct info from an XML data type into regular scalar variables based on conditions, however I am having trouble getting the correct info back.
Here is the XML I am searching through:
<Loop2420>
<NM1>
<F98_1>PW</F98_1>
<F1065>2</F1065>
</NM1>
<N3>
<F166>81715 DOCTOR CARRE</F166>
</N3>
<N4>
<F19>INDIO</F19>
<F156>CA</F156>
<F116>92201</F116>
</N4>
</Loop2420>
<Loop2420>
<NM1>
<F98_1>45</F98_1>
<F1065>2</F1065>
</NM1>
<N3>
<F166>51250 MECCA AVE</F166>
</N3>
<N4>
<F19>COACHELLA</F19>
<F156>CA</F156>
<F116>92236</F116>
</N4>
</Loop2420>
Basically I need to get the numbers from <'F116'> but only if <'F98_1'> is equal to 'PW'.
I have tried:
declare #zip varchar(30)
select #zip = T.value('(F116)[1]','varchar(30)')
from #TransactionXML.nodes('/Loop2420/N4') Trans(T)
where T.value('(/Loop2420/NM1/F98_1)[1]','varchar(30)') = 'PW'
But that sometimes returns the value from <'F116'> even if <'F98_1'> is equal to '45'.
Any suggestions? Thanks.
Put the test in the XQuery itself and clamp it to the node you're checking:
SELECT #zip = T.value('(N4/F116)[1]', 'varchar(30)')
FROM #TransactionXML.nodes('/Loop2420') Trans(T)
WHERE T.exist('NM1/F98_1[text()="PW"]') = 1
If PW is not a static value, use the sql:variable() or sql:column() function to incorporate it in the query.
Getting this error with the following query in SQL Server 2014.
SELECT
[Case]
,[Course]
,[Device]
,[IntegerValue]
,[Question]
,IFL.[QuestionSimplified]
,[Revision]
,[Script]
,[TextValue]
,[Timestamp]
,[Type]
,[Variable]
,[Wave]
FROM [dbo].[CosmosData] CD
Left Outer join [dbo].[ImportedFacilityList] IFL on CD.[Variable] = IFL.[Variablename]
where
CD.[Script] = 'CARD-F' and
(select * from [dbo].[CosmosData] where Variable = 'SURVEY_TYPE' and IntegerValue = '2')
When I run the above query I am getting the beloiw error,
Msg 4145, Level 15, State 1, Line 20
An expression of non-boolean type specified in a context where a condition is expected, near ')'.
Any help please?
You have this in the where clause:
and (select * from [dbo].[CosmosData] where Variable = 'SURVEY_TYPE' and IntegerValue = '2')
SQL needs a boolean expression. This is usually formed by using = or a similar comparison operator. In your case, I think you just exant exists:
exists (select * from [dbo].[CosmosData] where Variable = 'SURVEY_TYPE' and IntegerValue = 2)
That said, you might want a correlation clause as well.
Note: I removed the single quotes from the integer value. Only use single quotes for string and date constants.
based on the assumption that you are using case as a key in this table, you can use the follwing to return all rows from cosmos data where your conditions are applied and the select in your where clause has a match using the criteria within it.
SELECT
[Case]
,[Course]
,[Device]
,[IntegerValue]
,[Question]
,IFL.[QuestionSimplified]
,[Revision]
,[Script]
,[TextValue]
,[Timestamp]
,[Type]
,[Variable]
,[Wave]
FROM [dbo].[CosmosData] CD
Left Outer join [dbo].[ImportedFacilityList] IFL on CD.[Variable] = IFL. [Variablename]
where CD.[Script] = 'CARD-F'
and Case
IN
(select Case from [dbo].[CosmosData] where Variable = 'SURVEY_TYPE' and IntegerValue = '2')
Hope that helps any
My logic is faulty. Story of my life. Anyway, I have the following query, which I believe is failing during the multiple string checks in one column. I want to be able to check for multiple strings in one column with the AND operator.
Example, I want to suppress this email "dick1sucker#gmail.com" but I don't want to suppress "dickeynewman#gmail.com". Using the AND operator below, it appears as if a record is suppressed if either one of the string checks occurs, even though I've surrounded the statement with parentheses.
/****** Script for CHECK DOMAIN SUFFIX AND VULGARITIES ******/
SELECT EMAIL
INTO Matched_Table
FROM Matched_Table_TEMP
WHERE (RIGHT(RTRIM(EMAIL),4) IN ('.COM','.NET','.MIL','.GOV','.ORG','.BIZ') OR RIGHT(RTRIM(EMAIL),3) = '.US')
AND (CHARINDEX('DICK',EMAIL) = 0 and CHARINDEX('SUCKER',EMAIL) = 0)
AND (CHARINDEX('DICK',EMAIL) = 0 and CHARINDEX('HEAD',EMAIL) = 0)
AND (CHARINDEX('DICK',EMAIL) = 0 and CHARINDEX('CHOKE',EMAIL) = 0)
AND (CHARINDEX('DICK',EMAIL) = 0 and CHARINDEX('FACE',EMAIL) = 0)
AND (CHARINDEX('DICK',EMAIL) = 0 and CHARINDEX('NOSE',EMAIL) = 0)
AND (CHARINDEX('COCK',EMAIL) = 0 and CHARINDEX('SUCKER',EMAIL) = 0)
I will be adding plenty more vularities to the list, but obviously need the logic corrected first.
Another example, right now the above suppresses the following emails, but I don't want them suppressed.
METALHEAD038#HOTMAIL.COM
BAND2FACEDKITTY#AOL.COM
ANGELFACE30_98#YAHOO.COM
TERESADICKSON921#HOTMAIL.COM
ROARINGARTICHOKE#TOMGREEN.COM
CERNOSEK#YAHOO.COM
Change all your internal and's – the ones in lowercase – to or's.
Your query is selecting the valid addresses, so a more natural way to write your exclusions is like this:
AND NOT (A != 0 and B != 0)
With boolean logic, to negate p AND q you need to negate both parts and change the AND to OR: ~p OR ~q.
In your case:
AND (A = 0 or B = 0)
These are all AND conditions. You don't have a clause that will currently allow an e-mail address that contains dick at all, regardless of what the rest of the e-mail is. If you want to allow dick but not dick...head you need to think about this a little differently. E.g.
DECLARE #Email VARCHAR(255) = 'dickeynewman#gmail.com';
SELECT #Email
WHERE
(
RIGHT(RTRIM(#Email),4) IN ('.COM','.NET','.MIL','.GOV','.ORG','.BIZ')
OR RIGHT(RTRIM(#Email),3) = '.US'
)
AND
(
(#Email NOT LIKE '%DICK%')
OR
(#Email LIKE '%DICK%'
AND #Email NOT LIKE '%SUCKER%'
AND #Email NOT LIKE '%HEAD%'
-- ...
)
)
I have found out that my SQL 2008 R2 database is really struggling with COALESCE function if used within search.
CODE:
where
i.id_categ = COALESCE(#id_categ, i.id_categ )
and i.id_brand = COALESCE(#id_brand , i.id_brand )
and i.id_model = COALESCE(#id_model , i.id_model )
and i.id_type = COALESCE(#id_karoseria, i.id_type )
and i.id_fuel = COALESCE(#id_palivo, i.id_fuel )
and (i.year between #year_from and #year_to)
and (i.price between #price_from and #price_to)
DYNAMIC variables:
ALTER PROCEDURE [dbo].[spInzeratSelect]
#id_categ int = null,
#id_brand int = null,
#id_model int = null,
#id_fuel int = null,
#id_type int = null,
Search should work with or without these variables.
Benchmark:
with COALESCE = Total Execution Time: 3582
without COALESCE conditions = Total Execution Time: 13
You get the difference ...
Is there a nice solution how to ignore COALESCE and create dynamic SQL select with different approch ?
Thanks.
tIn your very specific case you should replace all your COALESCE search parameters with the following pattern:
AND ( (#id_brand IS NULL) OR (i.id_brand = #id_brand) )
etc
The parameter is evaluated as a literal before execution, so doing it this way makes the condition sargable.
This is functionally equivalent to your query except you're first checking against the literal value, which can be optimized away if it is, in fact, null.
EDIT: Apparently this is the approach recommended in #Joe Stefanelli's link as well. I originally poached it from Erland Sommerskog.
EDIT2: And I always forget to mention OPTION (RECOMPILE) too.