Domanda

Siamo scrittura di unit test per la nostra applicazione ASP.NET che funzionano contro un database di test di SQL Server. Cioè, il metodo ClassInitialize crea un nuovo database con dati di test, e il ClassCleanup elimina il database. Facciamo questo mediante l'esecuzione di script .bat dal codice.

Le classi in prova viene dato uno stringa di connessione che si connette al database di test unità anziché un database di produzione.

Il nostro problema è, che il database contiene un indice testo completo, che deve essere completamente popolato con i dati del test in modo che i nostri test da eseguire come previsto.

Per quanto posso dire, l'indice full-text è sempre popolata in background. Vorrei essere in grado, a:

  1. Crea l'indice completo di testo, completamente popolato, con un sincrono (Transact-SQL?) Dichiarazione, o
  2. Scopri quando la popolazione full-text è finito, c'è un'opzione di callback, o posso chiedere più volte?

La mia soluzione attuale è quella di forzare un ritardo alla fine il metodo della classe di inizializzazione - 5 secondi sembra funzionare -. Perché non riesco a trovare nulla nella documentazione

È stato utile?

Soluzione

E 'possibile interrogare lo stato utilizzando FULLTEXTCATALOGPROPERTY (vedi qui: http: // TechNet .microsoft.com / en-us / library / ms190370.aspx ).

Ad esempio:

SELECT
    FULLTEXTCATALOGPROPERTY(cat.name,'ItemCount') AS [ItemCount],
    FULLTEXTCATALOGPROPERTY(cat.name,'MergeStatus') AS [MergeStatus],
    FULLTEXTCATALOGPROPERTY(cat.name,'PopulateCompletionAge') AS [PopulateCompletionAge],
    FULLTEXTCATALOGPROPERTY(cat.name,'PopulateStatus') AS [PopulateStatus],
    FULLTEXTCATALOGPROPERTY(cat.name,'ImportStatus') AS [ImportStatus]
FROM sys.fulltext_catalogs AS cat

Si potrebbe anche come utilizzare SQL Profiler per monitorare ciò che i comandi problemi di SQL Server Management Studio quando si mettono le proprietà finestra di dialogo per il catalogo. La finestra di dialogo include un'indicatin dello stato della popolazione e tutte le informazioni visualizzate viene interrogato tramite T-SQL.

Altri suggerimenti

Vorrei offrire una versione più facile da leggere della risposta di @ Daniel Renshaw:

DECLARE @CatalogName VARCHAR(MAX)
SET     @CatalogName = 'FTS_Demo_Catalog'

SELECT
    DATEADD(ss, FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateCompletionAge'), '1/1/1990') AS LastPopulated
    ,(SELECT CASE FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
        WHEN 0 THEN 'Idle'
        WHEN 1 THEN 'Full Population In Progress'
        WHEN 2 THEN 'Paused'
        WHEN 3 THEN 'Throttled'
        WHEN 4 THEN 'Recovering'
        WHEN 5 THEN 'Shutdown'
        WHEN 6 THEN 'Incremental Population In Progress'
        WHEN 7 THEN 'Building Index'
        WHEN 8 THEN 'Disk Full.  Paused'
        WHEN 9 THEN 'Change Tracking' END) AS PopulateStatus
FROM sys.fulltext_catalogs AS cat

Risultati:

LastPopulated           PopulateStatus
----------------------- ----------------------------------
2012-05-08 14:51:37.000 Idle

(1 row(s) affected)

Questa è una stored procedure che abbiamo creato in base alla risposta del GarethOwen. Si accetta un elenco separato da virgole di tabelle come parametri e attende fino a quando gli indici full-text su tutti loro sono stati aggiornati. Lo fa questo controllo ogni decimo di secondo per evitare thrashing disco e timeout dopo 10 secondi nel caso in cui le cose sono in esecuzione lentamente / rotto. Utile se le ricerche di FT sono su più indici.

Chiamato nel seguente modo:

EXECUTE [dbo].[WaitForFullTextIndexing] 'MY_TABLE,ALTERNATE_NAMES,TAG_GROUP_VALUES,TAG_GROUPS,FIELD_OPTION';

La fonte:

CREATE PROCEDURE WaitForFullTextIndexing
    @TablesStr varchar(max)
AS
BEGIN
    DECLARE @Tables AS TABLE( [word] [varchar](8000) NULL)

    INSERT INTO @Tables (word) SELECT items from dbo.Split(@TablesStr, ',');

    DECLARE @NumberOfTables int;
    SELECT @NumberOfTables = COUNT(*) from @Tables;

    DECLARE @readyCount int;
    SET @readyCount = 0;

    DECLARE @waitLoops int;
    SET @waitLoops = 0;

    DECLARE @result bit;

    WHILE @readyCount <> @NumberOfTables AND @waitLoops < 100
    BEGIN

        select @readyCount = COUNT(*)
        from @Tables tabs
        where OBJECTPROPERTY(object_id(tabs.word), 'TableFulltextPopulateStatus') = 0;

        IF @readyCount <> @NumberOfTables
        BEGIN
            -- prevent thrashing
            WAITFOR DELAY '00:00:00.1';
        END

        set @waitLoops = @waitLoops + 1;

    END

END
GO

dbo.split è una funzione del valore tabella che tutti devono avere ormai che divide una stringa su un separatore in una tabella temporanea:

CREATE FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))        
returns @temptable TABLE (items varchar(8000))        
as        
begin        
    declare @idx int        
    declare @slice varchar(8000)        

    select @idx = 1        
        if len(@String)<1 or @String is null  return        

    while @idx!= 0        
    begin        
        set @idx = charindex(@Delimiter,@String)        
        if @idx!=0        
            set @slice = left(@String,@idx - 1)        
        else        
            set @slice = @String        

        if(len(@slice)>0)   
            insert into @temptable(Items) values(@slice)        

        set @String = right(@String,len(@String) - @idx)        
        if len(@String) = 0 break        
    end    
return        
end 

GO

Grazie Daniel, la tua risposta mi ha fatto sulla strada giusta.

Io in realtà utilizzare la seguente istruzione T-SQL per chiedere se lo stato della popolazione dell'indice testo completo è in standby:

SELECT OBJECTPROPERTY(object_id('v_doc_desc_de'), 'TableFulltextPopulateStatus')

'v_doc_desc_de' è il nome della vista database che abbiamo indice.

Se lo stato della popolazione non è inattivo, ho attendere un paio di secondi e di chiedere di nuovo, fino a quando è inattivo. E 'importante aspettare un po' di tempo tra i controlli per garantire alla popolazione di testo completo non è rallentato controllando continuamente lo stato della popolazione.

Il MSDN documentazione afferma che la funzione OBJECTPROPERTYEX (a livello di tabella) si consiglia l'affermazione FULLTEXTCATALOGPROPERTY con la proprietà 'PopulateStatus'. Essa afferma quanto segue:

  

Le seguenti proprietà verrà rimossa in una versione futura di SQL Server: logsize e PopulateStatus. Evitare l'uso di queste proprietà in nuovo progetto di sviluppo e prevedere interventi di modifica delle applicazioni che utilizzano uno qualsiasi di loro.

Per attendere un catalogo testo completo della popolazione finitura di tutte le sue tabelle e viste senza dover specificare i loro nomi, è possibile utilizzare la seguente stored procedure. Si tratta di una combinazione di risposta di JohnB a questa domanda e la risposta da cezarm ad una domanda relativa :

CREATE PROCEDURE WaitForFullTextIndexing
@CatalogName VARCHAR(MAX)
AS
BEGIN
    DECLARE @status int;
    SET @status = 1;
    DECLARE @waitLoops int;
    SET @waitLoops = 0;

    WHILE @status > 0 AND @waitLoops < 100
    BEGIN       
        SELECT @status = FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
        FROM sys.fulltext_catalogs AS cat;

        IF @status > 0
        BEGIN
            -- prevent thrashing
            WAITFOR DELAY '00:00:00.1';
        END
        SET @waitLoops = @waitLoops + 1;
    END
END
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top