2016-10-03 7 views
0

私はテーブル値関数(SQLite仮想テーブルとして)を実装しようとしています。xBestIndexの誤動作(テーブル値関数に非リテラルパラメータを渡す)

文字列を取り、文字列のすべての単語を含むテーブルを返す関数です。

私はそれを以下のようなリテラル値で呼び出すとうまくいきます。しかし、私は別のテーブルの列でそれを呼び出した場合

SELECT word FROM splitstring("abc def ghi") 

それは動作しません:

SELECT a.Name, word FROM article a, splitstring(a.Text) 

xBestIndexメソッドは、すべての権利と呼ばれるが、その直後、私は例外を取得ますExecuteReaderメソッドから取得します。例外メッセージは "xBestIndex malfunction"です。 xFilterメソッドは、例外のために呼び出されません。

マイxBestIndex実装はそれだけで私はxFilterでそれを見ることができるパラメータをマークし、簡単です:

public override SQLiteErrorCode BestIndex(SQLiteVirtualTable table, SQLiteIndex index) 
{ 
    index.Outputs.ConstraintUsages.ElementAt(0).argvIndex = 1; 
    index.Outputs.ConstraintUsages.ElementAt(0).omit = 1; 

    return SQLiteErrorCode.Ok; 
} 

私が何か間違ったことをやっているAMまたはそれが不可能大切なテーブルに非リテラルのパラメータを渡すことです機能?

+0

テーブルが結合される前にテーブル値関数が実行されるため、このクエリは意味がありません。 –

+0

それはそうかもしれないと私に気づいたが、そうではない。これは、table1の各行に対して1回実行されます。テーブル値関数の構文は、それが(同じ例外が発生)このクエリを書くだけで、別の方法だ、ただの構文suggarです: は \t a.Nameを選択して、内側の \t記事\t FROM をs.word s.phrase = a.Textにsplitstringを結合する – anakic

答えて

0

問題が見つかりました。私はusable=0の制約を使っていました。 BestIndexメソッドはSQLiteによって複数回呼び出されますが、2度目は使用できない制約があります。

ここはBestIndexメソッドの固定ボディです。

public override SQLiteErrorCode BestIndex(SQLiteVirtualTable table, SQLiteIndex index) 
{ 
    if (index.Inputs.Constraints.Count() != 2) 
     throw new ArgumentException("The generate_series function requires two integer (long) parameters!"); 

    if (index.Inputs.Constraints.All(c=>c.usable == 1)) 
    { 
     index.Outputs.ConstraintUsages.ElementAt(0).argvIndex = 1; 
     index.Outputs.ConstraintUsages.ElementAt(0).omit = 1; 
     index.Outputs.ConstraintUsages.ElementAt(1).argvIndex = 2; 
     index.Outputs.ConstraintUsages.ElementAt(1).omit = 1; 
    } 
    else 
    { 
     index.Outputs.IndexNumber = -1; 
     index.Outputs.EstimatedCost = double.MaxValue; 
    } 

    return SQLiteErrorCode.Ok; 
} 

ここで使用可能なフラグをチェックします。 BestIndexがusable=0の制約で呼び出されると、そのインデックスの見積もりコストが高いので、使用されないようにします。

関連する問題