2011-07-25 23 views
1

我正在翻译我使用表适配器和存储过程使用Linq to SQL(.NET 4)制作的ASP.NET网站,因为它使整个事情更可维护。LINQ到SQL全文搜索程序 - 奇怪的错误

该应用是图书馆目录,我在SQL Server 2008 R2 express中使用全文搜索,以允许用户搜索各种字段,如标题,作者,出版商等。 我现有的全文搜索是存储过程根据用户指定的搜索参数生成动态查询。在LinQ to SQL中,我计划重复使用这个相同的查询,因为没有直接访问全文搜索。

查询本身始终执行得很好。现在,我不断收到一个“全文谓词null或空”在运行时编译器,特别是在该行执行存储过程:

IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), section_ID, division_ID, start_Catalogue_Number, end_Catalogue_Number, start_Revision_Date, end_Revision_Date, start_Added_Date, end_Added_Date, book_Type, searchTitle, searchAuthor, searchPublisher, searchDealer, searchPrinter, searchSummary, searchComments, searchString, searchStringsCombinator, searchConditionsCombinator, pageNumber, pageSize, resultCount); 

所以,我曾尝试从头开始重建查询by子句添加条款的存储过程和全文搜索工作正常,直到“全文谓词空或空”错误再次出现。

我只是不能看到我在做什么是错的,它反复撞击我的头靠在一堵砖墙上。任何帮助将不胜感激。

存储过程这是工作,直到刚才是:

ALTER PROCEDURE dbo.AAATest 
(
    /*Non-fulltext search parameters*/ 
    @Section_ID int = null, 
    @Division_ID int = null, 
    @Start_Catalogue_Number int = null, 
    @End_Catalogue_Number int = null, 
    @Start_Revision_Date smalldatetime = null, 
    @End_Revision_Date smalldatetime = null, 
    @Start_Added_Date smalldatetime = null, 
    @End_Added_Date smalldatetime = null, 
    @Book_Type int = null, 

    /*Fulltext search parameters*/ 
    @SearchTitle bit = 0, 
    @SearchAuthor bit = 0, 
    @SearchPublisher bit = 0, 
    @SearchDealer bit = 0, 
    @SearchPrinter bit = 0, 
    @SearchSummary bit = 0, 
    @SearchComments bit = 0, 
    @SearchString nvarchar(4000) = NULL, 
    @SearchStringsCombinator nvarchar(3) = 'OR', 
    @SearchConditionsCombinator nvarchar(3) = 'OR', 

    /*Paging variables*/ 
    @PageNumber int = 0, 
    @PageSize int = 10, 

    /*Output parameters*/ 
    @ResultCount int OUTPUT 
) 

AS

DECLARE @DynamicSearchQuery nvarchar(MAX), 
     @DynamicSearchClause nvarchar(MAX), 
     @DynamicSearchParameters nvarchar(MAX), 
     @FullTextClauseSubjects nvarchar(MAX), 
     @FullTextClauseKeywords nvarchar(MAX) 

SELECT @DynamicSearchQuery = 'SELECT Teikoku_Lib_Current_Books.Book_ID, Teikoku_Lib_Current_Books.Book_Catalogue_Number, Teikoku_Lib_Current_Books.Book_ISBN_Number, Teikoku_Lib_Current_Books.Book_Title, Teikoku_Lib_Current_Books.Book_Author, Teikoku_Lib_Current_Books.Book_Publication_Date, Teikoku_Lib_Current_Books.Book_Revision_Date, Teikoku_Lib_Current_Books.Book_Publisher, Teikoku_Lib_Current_Books.Book_Edition_Date, Teikoku_Lib_Current_Books.Book_Edition_Number, Teikoku_Lib_Current_Books.Book_Printer, Teikoku_Lib_Current_Books.Book_Dealer, Teikoku_Lib_Current_Books.Book_Number_Of_Copies, Teikoku_Lib_Current_Books.Book_Part, Teikoku_Lib_Current_Books.Book_Summary, Teikoku_Lib_Current_Books.Book_Comments, Teikoku_Lib_Current_Books.Book_Section_ID, Teikoku_Lib_Current_Books.Book_Division_ID, Teikoku_Lib_Current_Books.Book_Added_Date, Teikoku_Lib_Current_Books.Book_Type'; 
    SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' ' + 'FROM Teikoku_Lib_Current_Books'; 
    SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' ' + 'WHERE '; 

/*Add static search conditions*/ 
/*Section and division data*/ 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Section_ID = @dynSection_ID OR @dynSection_ID IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Division_ID = @dynDivision_ID OR @dynDivision_ID IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
/*Book type*/ 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Type = @dynBook_Type OR @dynBook_Type IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
/*Catalogue number*/ 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Catalogue_Number >= @dynStart_Catalogue_Number OR @dynStart_Catalogue_Number IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Catalogue_Number <= @dynEnd_Catalogue_Number OR @dynEnd_Catalogue_Number IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
/*Revision date*/ 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Revision_Date >= @dynStart_Revision_Date OR @dynStart_Revision_Date IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Revision_Date <= @dynEnd_Revision_Date OR @dynEnd_Revision_Date IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Added_Date >= @dynStart_Added_Date OR @dynStart_Added_Date IS NULL)'; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + ' AND '; 
SELECT @DynamicSearchQuery = @DynamicSearchQuery + '(Teikoku_Lib_Current_Books.Book_Added_Date <= @dynEnd_Added_Date OR @dynEnd_Added_Date IS NULL)'; 

/*Dynamic search conditions*/ 
IF @SearchString IS NOT NULL 
BEGIN 

    /*Set combinator for the search strings*/ 
    IF @SearchStringsCombinator <> 'OR' AND @SearchStringsCombinator <> 'AND' 
     SELECT @SearchStringsCombinator = 'OR' 

    /*Replace underscore separators used in the querystring with the search string combinator keyword*/ 
    SELECT @SearchString = REPLACE(RTRIM(LTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@SearchString)), '_', ' '), ' ', ' '))), ' ', ' ' + @SearchStringsCombinator + ' '); 

    /*Fulltext search on the title*/ 
    IF @SearchTitle > 0 
     SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Title, @dynSearchString)'; 

    /*Fulltext search on the author*/ 
    IF @SearchAuthor > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Author, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' + 'AND CONTAINS(Teikoku_Lib_Current_Books.Book_Author, @dynSearchString)'; 
     END 

    /*Fulltext search on the publisher*/ 
    IF @SearchPublisher > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Publisher, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' + 'AND CONTAINS(Teikoku_Lib_Current_Books.Book_Publisher, @dynSearchString)'; 
     END 

    /*Fulltext search on the dealer*/ 
    IF @SearchDealer > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Dealer, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' +'CONTAINS(Teikoku_Lib_Current_Books.Book_Dealer, @dynSearchString)'; 
     END 

    /*Fulltext search on the printer*/ 
    IF @SearchPrinter > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Printer, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' + 'CONTAINS(Teikoku_Lib_Current_Books.Book_Printer, @dynSearchString)'; 
     END 

    /*Fulltext search on the summary*/ 
    IF @SearchSummary > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Summary, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' + 'CONTAINS(Teikoku_Lib_Current_Books.Book_Summary, @dynSearchString)'; 
     END 

    /*Fulltext search on the comments*/ 
    IF @SearchComments > 0 
     BEGIN 
     IF @DynamicSearchClause IS NULL 
      SELECT @DynamicSearchClause = 'CONTAINS(Teikoku_Lib_Current_Books.Book_Comments, @dynSearchString)'; 
     ELSE 
      SELECT @DynamicSearchClause = @DynamicSearchClause + ' ' + @SearchConditionsCombinator + ' ' + 'CONTAINS(Teikoku_Lib_Current_Books.Book_Comments, @dynSearchString)'; 
     END 

    /*Add the dynamic conditions to the query*/ 
    IF @DynamicSearchClause IS NOT NULL 
     SELECT @DynamicSearchQuery = @DynamicSearchQuery + 'AND (' + @DynamicSearchClause + ')'; 

END 

/*Dynamic query variables declaration*/ 
SELECT @DynamicSearchParameters = '@dynSection_ID int = null, @dynDivision_ID int = null, @dynStart_Catalogue_Number int = null, 
    @dynEnd_Catalogue_Number int = null, @dynStart_Revision_Date smalldatetime = null, @dynEnd_Revision_Date smalldatetime = null, 
    @dynStart_Added_Date smalldatetime = null, @dynEnd_Added_Date smalldatetime = null, @dynBook_Type int = null, @dynSearchString nvarchar(4000)'; 

/*Create table to hold results temporarily*/ 
CREATE table #searchResults 
(
    temp_Book_ID int IDENTITY(1,1), 
    Book_ID int, 
    Book_Catalogue_Number int, 
    Book_ISBN_Number nvarchar(13), 
    Book_Title nvarchar(200), 
    Book_Author nvarchar(200), 
    Book_Publication_Date datetime, 
    Book_Revision_Date datetime, 
    Book_Publisher nvarchar(100), 
    Book_Edition_Date datetime, 
    Book_Edition_Number smallint, 
    Book_Printer nvarchar(100), 
    Book_Dealer nvarchar(100), 
    Book_Number_Of_Copies int, 
    Book_Part int, 
    Book_Summary nvarchar(MAX), 
    Book_Comments nvarchar(MAX), 
    Book_Section_ID int, 
    Book_Division_ID int, 
    Book_Added_Date datetime, 
    Book_Type int 
) 

INSERT INTO #searchResults EXEC sp_executesql @DynamicSearchQuery, @DynamicSearchParameters, @Section_ID, @Division_ID, @Start_Catalogue_Number, 
    @End_Catalogue_Number, @Start_Revision_Date, @End_Revision_Date, @Start_Added_Date, @End_Added_Date, @Book_Type, @SearchString; 

SELECT #searchResults.Book_ID, #searchResults.Book_Catalogue_Number, #searchResults.Book_ISBN_Number, 
    #searchResults.Book_Title, #searchResults.Book_Author, #searchResults.Book_Publication_Date, #searchResults.Book_Revision_Date, 
    #searchResults.Book_Publisher, #searchResults.Book_Edition_Date, #searchResults.Book_Edition_Number, #searchResults.Book_Printer, 
    #searchResults.Book_Dealer, #searchResults.Book_Number_Of_Copies, #searchResults.Book_Part, #searchResults.Book_Summary, 
    #searchResults.Book_Comments, #searchResults.Book_Section_ID, #searchResults.Book_Division_ID, #searchResults.Book_Added_Date, 
    #searchResults.Book_Type 
    FROM #searchResults WHERE (#searchResults.temp_Book_ID >= (@PageNumber * @PageSize) AND #searchResults.temp_Book_ID <= ((@PageNumber + 1) * @PageSize)); 

SELECT @ResultCount = COUNT(*) FROM #searchResults; 

DROP TABLE #searchResults; 

RETURN 

我知道这是很长,很抱歉。但是,它本质上是一遍又一遍的相同的代码。 存储过程中的最后一位我需要获取查询返回的结果总数,以便我可以让我的分页界面正确显示。

我再打电话,从我的BLL作为

return db.AAATest(SectionID, DivisionID, StartCatalogueNumber, EndCatalogueNumber, StartRevisionDate, EndRevisionDate, 
     StartAddedDate, EndAddedDate, BookType, SearchTitle, SearchAuthor, SearchPublisher, SearchDealer, SearchPrinter, 
     SearchSummary, SearchComments, SearchStrings, SearchStringCombinator, 
     SearchConditionsCombinator, PageNumber, PageSize, ref TotalRecords); 

而作为一个测试,我传递参数

lvCatalogueContent.DataSource = currentBook_Repository.GetCurrentBooksFiltered(null, null, null, null, null, null, null, 
     null, null, true, false, false, false, false, false, false, true, true, "橋", null, null, null, null, null, 0, 20, 
     ref totalRecords); 

这些参数的工作精绝当我测试在SQL Server存储过程。 ..他们一直在ASP.NET中工作。

UPDATE:

我在编译器中得到确切的错误是:

SQLEXCEPTION: “null或空全文谓词” 等级:15 错误码:-2146232060

+0

完整的例外/错误的详细信息,请。 – leppie

+0

对不起,我还没有电脑,明天我会提出确切的错误(现在在日本晚上)。据我所知,它只是“说全文谓词空或空”,虽然。 –

+0

编译器错误代码会有帮助。 – leppie

回答

1

OK ,花了整整一个早上看存储过程后,我发现错误是由以下行引起的:

/*Replace underscore separators used in the querystring with the search string combinator keyword*/ 
SELECT @SearchString = REPLACE(RTRIM(LTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@SearchString)), '_', ' '), ' ', ' '))), ' ', ' ' + @SearchStringsCombinator + ' '); 

这是包裹在一个

IF @SearchString IS NOT NULL 
BEGIN 
END 

块,以避免不必要的额外计算的占比量,但是这似乎导致编译器认为,全文谓词为null或空。我已经移动了上一行,它检查combinator是否为OR或AND之外的包装如果块,它似乎工作(现在反正)...

另一种替代方法,我发现是处理搜索字符串调用存储过程之前的代码。

希望这有助于某人某一天。

+1

+1:感谢您发布您的解决方案。 – leppie