SQLSERVER全文搜索不能包含空格

解决方法:关键字加双引号

contains方法,尤其是CONTAINS([ff_Title], @ff_Title)此类用法中需要注意,Parameters中字符类型是不会自动添加双引号的,为了避免空格、逗号、or等搜索关键字引发数据库异常,应该在接口验证并手动处理搜索关键字,并且不应当手动关闭ASP.NET自带安全验证,否则会有sql注入风险。

搜索网站示例:https://www.ffxiv.cn/search/禁忌城邦 玛哈
当然正常搜索页面不推荐这样设计,无论是性能还是安全均不为最优。


遇到的具体问题示例。
在一个简易搜索页面,使用ASP.NET ListView直接显示搜索结果,SqlDataSource示例如下:

        <asp:SqlDataSource runat="server" ID="SqlDataSourceSearch" CacheDuration="180" 
            ConnectionString='<%$ ConnectionStrings:WebFFXIVMainConnectionString %>'
            SelectCommand="SELECT [ff_ArticleID], [ff_Title], [ff_ReleaseDate], [ff_Tags] FROM [FF_Article] WHERE (([ff_isCheck] = @ff_isCheck) AND ([ff_isOnlyImg] = @ff_isOnlyImg) AND ([ff_isShow] = @ff_isShow) AND ([ff_RightID] = @ff_RightID) AND (([ff_Tags] LIKE '%' + @ff_Tags + '%') OR (CONTAINS([ff_Title], @ff_Title)))) ORDER BY [ff_ModifyDate]">
            <SelectParameters>
                <asp:Parameter DefaultValue="true" Name="ff_isCheck" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="false" Name="ff_isOnlyImg" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="true" Name="ff_isShow" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="0" Name="ff_RightID" Type="Int32"></asp:Parameter>
                <asp:QueryStringParameter QueryStringField="keyword" Name="ff_Tags" Type="String"></asp:QueryStringParameter>
                <asp:QueryStringParameter QueryStringField="keyword" Name="ff_Title" Type="String"></asp:QueryStringParameter>
            </SelectParameters>
        </asp:SqlDataSource>

当全文搜索关键字包含空格或英文逗号等字符时会抛出异常

Exception information: 
    Exception type: SqlException 
    Exception message: 在全文搜索条件 '禁忌城邦 玛哈' 内的 '玛哈' 附近存在语法错误。

在代码改动最少的情况下,直接添加OnSelecting事件,在后台代码手动添加双引号,具体代码如下:
前台

        <asp:SqlDataSource runat="server" ID="SqlDataSourceSearch" CacheDuration="180" OnSelecting="SqlDataSourceSearch_Selecting"
            ConnectionString='<%$ ConnectionStrings:WebFFXIVMainConnectionString %>'
            SelectCommand="SELECT [ff_ArticleID], [ff_Title], [ff_ReleaseDate], [ff_Tags] FROM [FF_Article] WHERE (([ff_isCheck] = @ff_isCheck) AND ([ff_isOnlyImg] = @ff_isOnlyImg) AND ([ff_isShow] = @ff_isShow) AND ([ff_RightID] = @ff_RightID) AND (([ff_Tags] LIKE '%' + @ff_Tags + '%') OR (CONTAINS([ff_Title], @ff_Title)))) ORDER BY [ff_ModifyDate]">
            <SelectParameters>
                <asp:Parameter DefaultValue="true" Name="ff_isCheck" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="false" Name="ff_isOnlyImg" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="true" Name="ff_isShow" Type="Boolean"></asp:Parameter>
                <asp:Parameter DefaultValue="0" Name="ff_RightID" Type="Int32"></asp:Parameter>
                <asp:QueryStringParameter QueryStringField="keyword" Name="ff_Tags" Type="String"></asp:QueryStringParameter>
                <asp:QueryStringParameter QueryStringField="keyword" Name="ff_Title" Type="String"></asp:QueryStringParameter>
            </SelectParameters>
        </asp:SqlDataSource>

后台

        protected void SqlDataSourceSearch_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
        {
            e.Command.Parameters[5].Value = "\"" + e.Command.Parameters[5].Value.ToString() + "\"";
        }