67

テスト SQL Server データベースに対して実行される ASP.NET アプリケーションの単体テストを作成しています。つまり、ClassInitialize メソッドはテスト データを含む新しいデータベースを作成し、ClassCleanup はデータベースを削除します。これを行うには、コードから .bat スクリプトを実行します。

テスト対象のクラスには、運用データベースではなく単体テスト データベースに接続する接続文字列が与えられます。

問題は、データベースにフルテキスト インデックスが含まれていることです。テストを期待どおりに実行するには、テスト データを完全に入力する必要があります。

私の知る限り、フルテキスト インデックスは常にバックグラウンドで作成されます。次のいずれかを実行できるようにしたいと考えています。

  1. 同期 (transact-SQL?) ステートメントを使用して、完全に入力されたフルテキスト インデックスを作成する、または
  2. フルテキスト作成がいつ終了するか、コールバック オプションはありますか、それとも繰り返し質問できますか?

私の現在の解決策は、クラスのinitializeメソッドの最後に遅延を強制することです-5秒でうまくいくようです-ドキュメントに何も見つからないためです。

4

6 に答える 6

74

@DanielRenshawの答えの読みやすいバージョンを提供したいと思います。

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

結果:

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

(1 row(s) affected)
于 2012-05-08T19:52:21.693 に答える
53

FULLTEXTCATALOGPROPERTYを使用してステータスを照会できます(http://technet.microsoft.com/en-us/library/ms190370.aspxを参照)。

例えば:

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

また、SQL Profilerを使用して、カタログのプロパティダイアログを表示するときにSQL ServerManagementStudioが発行するコマンドを監視することもできます。ダイアログには人口ステータスの表示が含まれ、表示されるすべての情報はT-SQLを使用して照会されます。

于 2010-04-28T08:47:53.827 に答える
12

これは、GarethOwen の回答に基づいて作成したストアド プロシージャです。テーブルのコンマ区切りリストをパラメータとして受け取り、それらすべての全文索引が更新されるまで待機します。ディスクのスラッシングを防ぐために 10 分の 1 秒ごとにこのチェックを行い、動作が遅い/壊れている場合に備えて 10 秒後にタイムアウトします。FT 検索が複数のインデックスにまたがる場合に便利です。

次の方法で呼び出されます。

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

起源:

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 は、セパレーターの文字列を一時テーブルに分割する、誰もが持っているはずのテーブル値関数です。

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
于 2011-10-31T12:11:28.593 に答える
8

ダニエルに感謝します。あなたの答えは私を正しい軌道に乗せました。

実際に次の T-SQL ステートメントを使用して、フルテキスト インデックスの作成ステータスが Idle かどうかを確認します。

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

「v_doc_desc_de」は、インデックスを作成するデータベース ビューの名前です。

ポピュレーション ステータスがアイドル状態でない場合は、数秒待ってから、アイドル状態になるまで再度質問します。ポピュレーション ステータスを継続的にチェックすることで、フル テキストのポピュレーションが遅くならないように、チェックの間隔を少し空けることが重要です。

MSDNのドキュメントでは、プロパティ 'PopulateStatus' を使用OBJECTPROPERTYEXするステートメントよりも関数 (テーブル レベル) を使用することをお勧めします。FULLTEXTCATALOGPROPERTY次のように述べています。

次のプロパティは、SQL Server の将来のリリースで削除される予定です: LogSize および PopulateStatus。新しい開発作業でこれらのプロパティを使用することは避け、現在それらのいずれかを使用しているアプリケーションを変更することを計画してください。

于 2010-04-28T16:21:48.810 に答える