Pregunta

Nos dirigimos pruebas unitarias para nuestra aplicación ASP.NET que se ejecutan en una base de datos de prueba de SQL Server. Es decir, el método ClassInitialize crea una nueva base de datos con datos de prueba, y la ClassCleanup elimina la base de datos. Hacemos esto mediante la ejecución de secuencias de comandos .bat de código.

Las clases bajo prueba se les da una cadena de conexión que se conecta a la base de datos de prueba de unidad en lugar de una base de datos de producción.

Nuestro problema es, que la base de datos contiene un índice de texto completo, que debe ser totalmente lleno con los datos de prueba a fin de que nuestras pruebas se ejecuten como se esperaba.

Por lo que yo puedo decir, el índice de texto completo siempre se rellena en el fondo. Me gustaría ser capaz de, ya sea:

  1. Crea el índice de texto completo, totalmente poblada, con una sincrónica (Transact-SQL?) Declaración, o
  2. Para saber cuando la población de texto completo está terminado, hay una opción de devolución de llamada, o puedo pedir repetidamente?

Mi solución actual es forzar un retraso al final del método de inicialización de clase - 5 segundos parece funcionar -. Porque no puedo encontrar nada en la documentación

¿Fue útil?

Solución

Se puede consultar el estado usando FULLTEXTCATALOGPROPERTY (ver aquí: http: // TechNet .microsoft.com / es-es / library / ms190370.aspx ).

Por ejemplo:

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

Es posible que también les gusta usar SQL para controlar lo que emite comandos SQL Server Management Studio cuando aparezca el diálogo de propiedades para el catálogo. El cuadro de diálogo incluye una indicatin de estado de la población y toda la información que se muestra es consultado usando T-SQL.

Otros consejos

Me gustaría ofrecer una versión más fácil de leer la respuesta de Renshaw @ Daniel:

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

Resultados:

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

(1 row(s) affected)

Este es un procedimiento almacenado que crea basándose en la respuesta de GarethOwen. Se acepta una lista separada por comas de las tablas como parámetros y espera hasta que los índices de texto completo sobre todos ellos han sido actualizados. Lo hace esta comprobación cada décima de segundo para prevenir latigazos, el disco y el tiempo de espera después de 10 segundos por si las cosas están funcionando lentamente / roto. Es útil si tus búsquedas FT son a través de múltiples índices.

Llamado de la siguiente manera:

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

La fuente:

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 es una función de valor de tabla que todo el mundo debe tener por ahora, que divide una cadena en un separador en una tabla temporal:

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

Gracias Daniel, su respuesta me puso en el camino correcto.

En realidad, utilizar la siguiente instrucción T-SQL para preguntar si el estado de la población del índice de texto completo está inactivo:

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

'v_doc_desc_de' es el nombre de la vista base de datos que nos índice.

Si el estado de la población no está inactivo, me espera un par de segundos y volver a preguntar, hasta que esté inactivo. Es importante esperar una pequeña cantidad de tiempo entre comprobaciones para asegurar la población texto completo no se ralentiza comprobando continuamente el estado de la población.

El MSDN la documentación establece que la función OBJECTPROPERTYEX (a nivel de tabla) se recomienda más que la declaración FULLTEXTCATALOGPROPERTY con la propiedad 'PopulateStatus'. Se afirma lo siguiente:

  

Las siguientes propiedades se quitará en una versión futura de SQL Server: logsize y PopulateStatus. Evitar el uso de estas propiedades en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente usan cualquiera de ellos.

Para esperar un catálogo de texto completo a la población llegada de todas sus tablas y vistas sin tener que especificar sus nombres, se puede utilizar el siguiente procedimiento almacenado. Esta es una combinación de la respuesta de JohnB a esta pregunta y la respuesta por cezarm a una pregunta relacionada :

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top