Pregunta

Is it possible to use FULLTEXT indexing with a view in Sql Server without creating the index on the view itself?

I was quite surprised to find that using CONTAINS(,) to query a column in a view doesn't work:

IF OBJECT_ID('ExampleTable') IS NULL
CREATE TABLE ExampleTable (
    SurrogateKey INT NOT NULL,
    Text VARCHAR(100)
)

TRUNCATE TABLE ExampleTable;
INSERT INTO ExampleTable VALUES (1, 'Lorem ipsum dolor sit amet')
INSERT INTO ExampleTable VALUES (2, 'consectetur adipisicing elit')

IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name='PK_ExampleTable')
CREATE UNIQUE CLUSTERED INDEX PK_ExampleTable ON ExampleTable (
    SurrogateKey
)
GO

IF 'ExampleFullTextCatalog' NOT IN (SELECT name from sys.fulltext_catalogs)
CREATE FULLTEXT CATALOG ExampleFullTextCatalog;

IF OBJECT_ID('ExampleTable') NOT IN (SELECT OBJECT_ID from sys.fulltext_indexes)
CREATE FULLTEXT INDEX ON ExampleTable
(
    Text Language 1033
)
KEY INDEX PK_ExampleTable
ON ExampleFullTextCatalog
WITH CHANGE_TRACKING AUTO
GO

-- Wait for the full text index to populate for the example code
WHILE EXISTS (SELECT FULLTEXTCATALOGPROPERTY('ExampleFullTextCatalog','PopulateStatus') EXCEPT SELECT 0)
    CONTINUE


IF OBJECT_ID('ExampleView') IS NULL
EXEC ('CREATE VIEW ExampleView AS SELECT Text FROM ExampleTable')
GO

SELECT Text FROM ExampleTable WHERE CONTAINS(Text, 'ipsum')
GO

SELECT Text FROM ExampleView WHERE CONTAINS(Text, 'ipsum')
GO

DROP VIEW ExampleView
DROP FULLTEXT INDEX ON ExampleTable
DROP INDEX PK_ExampleTable ON ExampleTable
DROP TABLE ExampleTable
DROP FULLTEXT CATALOG ExampleFullTextCatalog

The first select from the table, SELECT Text FROM ExampleTable WHERE CONTAINS(Text, 'ipsum'), returns

Text
--------------------------
Lorem ipsum doler sit amet

as exepected. But the second select from the view, SELECT Text FROM ExampleView WHERE CONTAINS(Text, 'ipsum'), results in the following error:

Msg 7601, Level 16, State 2, Line 2
Cannot use a CONTAINS or FREETEXT predicate on table or indexed view 'ExampleView' because it is not full-text indexed.

The database is at compatibility level 100 (Sql Server 2008).

¿Fue útil?

Solución

How about putting the FTI on the table and creating a parameterized table function that works with the FTI? You can use CROSS APPLY in your joins inside of your views to join a function as a table or just use it in a where clause if the function parameter value is static to the consuming view.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top