-2

I have a problem using the sql server full text with parameter

Alter Procedure[dbo].[SelectFullName]
@fullname nvarchar(45)
As
Select*from [dbo][NamePersonTB]
Where CONTAINS (fullname,'"*@fullname*"')

I want to use SAME LIKE to fullname

Lazard
  • 11
  • 3
  • Tag spam doesn't help us help you; it makes it harder to. Tagging multiple conflicting tags means that we have no idea what technology you are really asking about, making your question unclear and difficult to answer. Tagging completely irrelevant technologies just wastes the time of the subject experts you attract that know nothing about the technology you are *actually* asking about. Either way, tag spam can easily end up attracting downvotes and also close votes if they make the question unclear. Just tag the technologies you are actually asking about. I've removed almost all the tags here. – Thom A Feb 25 '22 at 12:34
  • As for your SQL, it's malformed (you're missing a part separator between the schema and table name). For the problem, have you tried concatenation? `fullname` in the literal string `'"*fullname*"'` won't be replaced by the value of the parameter `@fullname`. – Thom A Feb 25 '22 at 12:37
  • Contains (fullname,'"*@fullname*"') I have error in "'*@fullname*"' – Lazard Feb 25 '22 at 12:41
  • Like i said, use concatenation.Why can't you do `CONCAT('"*',@fullname,'*"')`? – Thom A Feb 25 '22 at 12:43
  • !!? An express of non-boolean type.... and I used concatenation and it didn't work – Lazard Feb 25 '22 at 12:53
  • What does "It didn't work" mean? Do you get an error, do you get unexpected resuts? Undesired behaviour? Something else? – Thom A Feb 25 '22 at 12:55
  • [Edit] your question and post your new attempts. That error won't occur for `CONTAINS`. – Thom A Feb 25 '22 at 12:59
  • Sorry, this is true, but when I search for a name, for example, John Michael, it does not show a result, I expect it to be considered '"*fullname*"' is string not parameter Iwant use @fullname and when search the result show same when I use LIKE ...thank you – Lazard Feb 25 '22 at 13:06
  • You can't use a calculate value in that position. You would have to use dynamic SQL. See also https://stackoverflow.com/questions/5152783/tsql-a-join-using-full-text-contains – Charlieface Feb 25 '22 at 13:23
  • Probably want to use a different variable, @Charlieface , as `@fullname` is only defined as a `nvarchar(16)` (not much space for a full name) which would leave only 14 characters for a "full" name. – Thom A Feb 25 '22 at 13:25
  • @Larnu I changed it to nvarchar(45) – Lazard Feb 25 '22 at 13:49
  • Thanks for your answer, I can use Where CONTAINS (fullname,@fullname) in full text search when I search for a name, for example, John Michael, the result show John Michael but I want when search John the result show John Michael What do I have to edit here?CONTAINS (fullname,'"*@fullname*"') @Charlieface – Lazard Feb 25 '22 at 13:58

1 Answers1

0

You are using the @Fullname as a literal string by wrapping it in single quotes. You need to pass a variable directly into the CONTAINS function if you want to use the actual value of @Fullname as your search criteria

Also note you cannot do the %SearchTerm% exactly the same way if you want to leverage your fulltext index. You can search for words that have a matching prefix, but not matching suffix/middle. For more info on wildcard(*) usage with CONTAINS, see <prefix_term> section in the MS doc

Below I've created two ways I might set up the fulltext search, a simple version and a more advanced. Not sure your business needs, but the more advanced fully leverages the fulltext index and has a "smart" ranking option that is pretty neat

Table Setup

CREATE TABLE NamePersonTB (ID INT IDENTITY(1,1) CONSTRAINT PK_NamePersonTB Primary Key,FullName NVARCHAR(100))
INSERT INTO NamePersonTB
VALUES ('John Smith')
    ,('Jane Smith')
    ,('Bill Gates')
    ,('Satya Nadella')

CREATE FULLTEXT CATALOG ct_test AS DEFAULT;
CREATE FULLTEXT INDEX ON NamePersonTB(FullName) KEY INDEX PK_NamePersonTB;

Fulltext Search Script

DECLARE @FullName NVARCHAR(45);

/*Sample searches*/
SET @FullName = 'John Smith' /*Notice John Smith appears first in ranked search*/
--SET @FullName = 'Smith'
--SET @FullName = 'Sm'
--SET @FullName = 'Bill'

DECLARE @SimpleContainsSearchCriteria NVARCHAR(1000)
    ,@RankedContainsSearchCriteria NVARCHAR(1000)

/*
Below will
    1. Parses the words into rows
    2. Adds wildcard to end(cannot add wildcard to prefix according to MS doc on CONTAINS)
    3. Combines all words back into single row with separator to create CONTAINS search criteria
*/
SELECT @SimpleContainsSearchCriteria  = STRING_AGG(CONCAT('"',A.[Value],'*"'),' AND ')
FROM STRING_SPLIT(REPLACE(@Fullname,'"',''),' ') AS A /*REPLACE() removes any double quotes as they will break your search*/

/*Same as above, but uses OR to include more results and will utilize [Rank] so better matches appear first*/
SELECT @RankedContainsSearchCriteria = STRING_AGG(CONCAT('"',A.[Value],'*"'),' OR ')
FROM STRING_SPLIT(REPLACE(@Fullname,'"',''),' ') AS A 

/*Included so you can see the search critieria. Should remove in final proc*/
SELECT @Fullname AS FullNameInput
    ,@SimpleContainsSearchCriteria  AS SimpleSearchCriteria
    ,@RankedContainsSearchCriteria AS RankedContainsSearchCriteria

/*Simple AND match*/
SELECT *
FROM NamePersonTB AS A 
WHERE CONTAINS(FullName,@SimpleContainsSearchCriteria)

/*CONTAINSTABLE match alternative. Uses OR criteria and then ranks so best matches appear at the top*/
SELECT *
FROM CONTAINSTABLE(NamePersonTB,FullName,@RankedContainsSearchCriteria) AS A
INNER JOIN NamePersonTB AS B
    ON A.[Key] = B.ID
ORDER BY A.[Rank] DESC

Sample Search Criteria

FullNameInput SimpleSearchCriteria RankedContainsSearchCriteria
John Smith "John*" AND "Smith*" "John*" OR "Smith*"

Output of Simple Search

ID FullName
1 John Smith

Output of Ranked Search

KEY RANK ID FullName
1 48 1 John Smith
2 32 2 Jane Smith
Stephan
  • 5,891
  • 1
  • 16
  • 24