0

我目前正在使用 Irony 作为我的搜索系统的一部分,我遇到了无数关于不正确语法的问题,我已经设法缩小了范围,但现在我被困在最后一个似乎与某些关键字有关的问题上。

如果您要搜索包含“或”或“和”的任何内容,则它会在 SQL 搜索字符串中返回语法错误。

对于其他问题,我只是简单地逃脱了流氓字符或完全从搜索中删除它们,但这似乎不是一个可行的解决方案,因为这些词可能是我们搜索的一部分。

Irony 链接:http: //irony.codeplex.com/

       if (!string.IsNullOrEmpty(fTextSearch))
            {
                sql.AppendLine("UNION");
                sql.AppendLine(commonClause);
                sql.AppendLine(string.Format("AND CONTAINS(nt.text, '{0}', LANGUAGE 'English')", fTextSearch));
            }

        IList<Product> results = query.List<Product>();

当联合被添加到字符串中时,它会导致它崩溃并抛出错误,并且错误出现在最后一行。

实际错误是:

Syntax error near 'gum' in the full-text search condition 'orbit gum'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Data.SqlClient.SqlException: Syntax error near 'gum' in the full-text search condition 'orbit gum'.

目前如何解决其他问题;

    private string[] syntaxErrorChars = { "{", "}", "[", "]", "and", "(", ")" };
    private string[] errorChars = { "'", "&", "/", "\\", "~", "@" };

        if (compiler.Parser.GetErrors().Count == 0)
        {
            AstNode root = compiler.Parse(phrase.ToLower());
            if (compiler.Parser.GetErrors().Count == 0)
            {
                try
                {

                    fTextSearch = SearchGrammar.ConvertQuery(root, SearchGrammar.TermType.Inflectional);
                }
                catch
                {
                    fTextSearch = phrase;
                }
            }
            else
            {
                fTextSearch = phrase;
            }
        }
        else
        {
            fTextSearch = phrase;
        }



        //Escape Search String
        StringBuilder sb = new StringBuilder();

        string[] splitString = fTextSearch.Split(errorChars, StringSplitOptions.None);

        int numNewCharactersAdded = 0;
        foreach (string itm in splitString)
        {
            sb.Append(itm); //append string
            if (fTextSearch.Length > (sb.Length - numNewCharactersAdded))
            {
                sb.Append(fTextSearch[sb.Length - numNewCharactersAdded]); //append splitting character
                sb.Append(fTextSearch[sb.Length - numNewCharactersAdded - 1]); //append it again
                numNewCharactersAdded++;
            }
        }

        if(!string.IsNullOrEmpty(sb.ToString()))
            fTextSearch = sb.ToString();
        //Escaping Finished

        //Remove Syntax breaking characters
        for (int i = 0; i < syntaxErrorChars.Count(); i++)
        {
            fTextSearch = fTextSearch.Replace(syntaxErrorChars[i], string.Empty);
        }
        //Finished Syntax breaking characters.

给出错误时的实际查询是:

    SELECT DISTINCT prod.prod_id as node1_76_0_, prod.stock_code as stock2_95_0_, prod.supplier_part_number as supplier3_95_0_, prod.sold_in_multiple as sold4_95_0_, prod.free as free95_0_, prod.poa as poa95_0_, prod.allow_back_order as allow7_95_0_, prod.stock_threshold as stock8_95_0_, prod.low_stock_threshold as low9_95_0_, prod.tax_type as tax10_95_0_, prod.nominal_sale as nominal11_95_0_, prod.nominal_purchase as nominal12_95_0_, prod.commodity_code as commodity13_95_0_, prod.preferred_alternative as preferred14_95_0_, prod.role as role95_0_, prod.stock_type as stock16_95_0_, prod.weight as weight95_0_, prod.imported_by as imported18_95_0_, prod.import_code as import19_95_0_, prod.customisable as customi20_95_0_, prod.customisable_prompt as customi21_95_0_, prod.agent_only as agent22_95_0_, prod.sell_to_retail as sell23_95_0_, prod.sell_to_trade as sell24_95_0_, prod.sell_by_decimal as sell25_95_0_, prod.length as length95_0_, prod.breadth as breadth95_0_, prod.width as width95_0_, prod.hazardous as hazardous95_0_, prod.fragile as fragile95_0_, prod.liquid as liquid95_0_, prod.palletised as palletised95_0_, prod.attractive as attractive95_0_, prod.boxed as boxed95_0_, prod.charge_code as charge35_95_0_, prod.discount_code as discount36_95_0_, prod.floor_price as floor37_95_0_, prod.cost_price as cost38_95_0_, prod.crm as crm95_0_, prod.category as category95_0_, prod.sub_category as sub41_95_0_, prod_1_.version_number as version2_76_0_, prod_1_.[name] as name3_76_0_, prod_1_.visible_on_website as visible4_76_0_, prod_1_.url_part as url5_76_0_, prod_1_.parent as parent76_0_, prod_1_.bnd_id as bnd7_76_0_, prod_1_.template as template76_0_, prod_1_.custom_string_1 as custom9_76_0_, prod_1_.custom_string_2 as custom10_76_0_, prod_1_.custom_string_3 as custom11_76_0_, prod_1_.custom_string_4 as custom12_76_0_, prod_1_.custom_string_5 as custom13_76_0_, prod_1_.custom_bool_1 as custom14_76_0_, prod_1_.custom_bool_2 as custom15_76_0_, prod_1_.custom_bool_3 as custom16_76_0_, prod_1_.custom_bool_4 as custom17_76_0_, prod_1_.custom_bool_5 as custom18_76_0_, prod_1_.custom_decimal_1 as custom19_76_0_, prod_1_.custom_decimal_2 as custom20_76_0_, prod_1_.custom_decimal_3 as custom21_76_0_, prod_1_.custom_decimal_4 as custom22_76_0_, prod_1_.custom_decimal_5 as custom23_76_0_, prod_1_.created as created76_0_, prod_1_.updated as updated76_0_, prod_1_.created_by as created26_76_0_, prod_1_.updated_by as updated27_76_0_, prod_1_.flags as flags76_0_, prod_1_.active as active76_0_
FROM tbl_ecom_cat_product prod
   INNER JOIN tbl_ecom_cat_node prod_1_ ON prod_1_.node_id = prod.prod_id
   LEFT OUTER JOIN tbl_ecom_cat_node_text nt ON prod.prod_id = nt.node_id
   LEFT OUTER JOIN tbl_ecom_shipping_service AS s ON prod.role = s.shs_id
WHERE (
    s.shs_id IS NULL
)
AND ( prod_1_.visible_on_website = 1 )

AND ( prod_1_.name LIKE ?
    OR prod.stock_code LIKE ?
    OR prod.supplier_part_number LIKE ?
)
AND ( prod_1_.name LIKE ?
    OR prod.stock_code LIKE ?
    OR prod.supplier_part_number LIKE ?
)
UNION
SELECT DISTINCT prod.prod_id as node1_76_0_, prod.stock_code as stock2_95_0_, prod.supplier_part_number as supplier3_95_0_, prod.sold_in_multiple as sold4_95_0_, prod.free as free95_0_, prod.poa as poa95_0_, prod.allow_back_order as allow7_95_0_, prod.stock_threshold as stock8_95_0_, prod.low_stock_threshold as low9_95_0_, prod.tax_type as tax10_95_0_, prod.nominal_sale as nominal11_95_0_, prod.nominal_purchase as nominal12_95_0_, prod.commodity_code as commodity13_95_0_, prod.preferred_alternative as preferred14_95_0_, prod.role as role95_0_, prod.stock_type as stock16_95_0_, prod.weight as weight95_0_, prod.imported_by as imported18_95_0_, prod.import_code as import19_95_0_, prod.customisable as customi20_95_0_, prod.customisable_prompt as customi21_95_0_, prod.agent_only as agent22_95_0_, prod.sell_to_retail as sell23_95_0_, prod.sell_to_trade as sell24_95_0_, prod.sell_by_decimal as sell25_95_0_, prod.length as length95_0_, prod.breadth as breadth95_0_, prod.width as width95_0_, prod.hazardous as hazardous95_0_, prod.fragile as fragile95_0_, prod.liquid as liquid95_0_, prod.palletised as palletised95_0_, prod.attractive as attractive95_0_, prod.boxed as boxed95_0_, prod.charge_code as charge35_95_0_, prod.discount_code as discount36_95_0_, prod.floor_price as floor37_95_0_, prod.cost_price as cost38_95_0_, prod.crm as crm95_0_, prod.category as category95_0_, prod.sub_category as sub41_95_0_, prod_1_.version_number as version2_76_0_, prod_1_.[name] as name3_76_0_, prod_1_.visible_on_website as visible4_76_0_, prod_1_.url_part as url5_76_0_, prod_1_.parent as parent76_0_, prod_1_.bnd_id as bnd7_76_0_, prod_1_.template as template76_0_, prod_1_.custom_string_1 as custom9_76_0_, prod_1_.custom_string_2 as custom10_76_0_, prod_1_.custom_string_3 as custom11_76_0_, prod_1_.custom_string_4 as custom12_76_0_, prod_1_.custom_string_5 as custom13_76_0_, prod_1_.custom_bool_1 as custom14_76_0_, prod_1_.custom_bool_2 as custom15_76_0_, prod_1_.custom_bool_3 as custom16_76_0_, prod_1_.custom_bool_4 as custom17_76_0_, prod_1_.custom_bool_5 as custom18_76_0_, prod_1_.custom_decimal_1 as custom19_76_0_, prod_1_.custom_decimal_2 as custom20_76_0_, prod_1_.custom_decimal_3 as custom21_76_0_, prod_1_.custom_decimal_4 as custom22_76_0_, prod_1_.custom_decimal_5 as custom23_76_0_, prod_1_.created as created76_0_, prod_1_.updated as updated76_0_, prod_1_.created_by as created26_76_0_, prod_1_.updated_by as updated27_76_0_, prod_1_.flags as flags76_0_, prod_1_.active as active76_0_
FROM tbl_ecom_cat_product prod
   INNER JOIN tbl_ecom_cat_node prod_1_ ON prod_1_.node_id = prod.prod_id
   LEFT OUTER JOIN tbl_ecom_cat_node_text nt ON prod.prod_id = nt.node_id
   LEFT OUTER JOIN tbl_ecom_shipping_service AS s ON prod.role = s.shs_id
WHERE (
    s.shs_id IS NULL
)
AND ( prod_1_.visible_on_website = 1 )

AND CONTAINS(nt.text, 'orbit gum', LANGUAGE 'English')
 ]
  Name: wildcard1 - Value: %gum%
  Name: wildcard0 - Value: %orbit%
[SQL: SELECT DISTINCT prod.prod_id as node1_76_0_, prod.stock_code as stock2_95_0_, prod.supplier_part_number as supplier3_95_0_, prod.sold_in_multiple as sold4_95_0_, prod.free as free95_0_, prod.poa as poa95_0_, prod.allow_back_order as allow7_95_0_, prod.stock_threshold as stock8_95_0_, prod.low_stock_threshold as low9_95_0_, prod.tax_type as tax10_95_0_, prod.nominal_sale as nominal11_95_0_, prod.nominal_purchase as nominal12_95_0_, prod.commodity_code as commodity13_95_0_, prod.preferred_alternative as preferred14_95_0_, prod.role as role95_0_, prod.stock_type as stock16_95_0_, prod.weight as weight95_0_, prod.imported_by as imported18_95_0_, prod.import_code as import19_95_0_, prod.customisable as customi20_95_0_, prod.customisable_prompt as customi21_95_0_, prod.agent_only as agent22_95_0_, prod.sell_to_retail as sell23_95_0_, prod.sell_to_trade as sell24_95_0_, prod.sell_by_decimal as sell25_95_0_, prod.length as length95_0_, prod.breadth as breadth95_0_, prod.width as width95_0_, prod.hazardous as hazardous95_0_, prod.fragile as fragile95_0_, prod.liquid as liquid95_0_, prod.palletised as palletised95_0_, prod.attractive as attractive95_0_, prod.boxed as boxed95_0_, prod.charge_code as charge35_95_0_, prod.discount_code as discount36_95_0_, prod.floor_price as floor37_95_0_, prod.cost_price as cost38_95_0_, prod.crm as crm95_0_, prod.category as category95_0_, prod.sub_category as sub41_95_0_, prod_1_.version_number as version2_76_0_, prod_1_.[name] as name3_76_0_, prod_1_.visible_on_website as visible4_76_0_, prod_1_.url_part as url5_76_0_, prod_1_.parent as parent76_0_, prod_1_.bnd_id as bnd7_76_0_, prod_1_.template as template76_0_, prod_1_.custom_string_1 as custom9_76_0_, prod_1_.custom_string_2 as custom10_76_0_, prod_1_.custom_string_3 as custom11_76_0_, prod_1_.custom_string_4 as custom12_76_0_, prod_1_.custom_string_5 as custom13_76_0_, prod_1_.custom_bool_1 as custom14_76_0_, prod_1_.custom_bool_2 as custom15_76_0_, prod_1_.custom_bool_3 as custom16_76_0_, prod_1_.custom_bool_4 as custom17_76_0_, prod_1_.custom_bool_5 as custom18_76_0_, prod_1_.custom_decimal_1 as custom19_76_0_, prod_1_.custom_decimal_2 as custom20_76_0_, prod_1_.custom_decimal_3 as custom21_76_0_, prod_1_.custom_decimal_4 as custom22_76_0_, prod_1_.custom_decimal_5 as custom23_76_0_, prod_1_.created as created76_0_, prod_1_.updated as updated76_0_, prod_1_.created_by as created26_76_0_, prod_1_.updated_by as updated27_76_0_, prod_1_.flags as flags76_0_, prod_1_.active as active76_0_
FROM tbl_ecom_cat_product prod
   INNER JOIN tbl_ecom_cat_node prod_1_ ON prod_1_.node_id = prod.prod_id
   LEFT OUTER JOIN tbl_ecom_cat_node_text nt ON prod.prod_id = nt.node_id
   LEFT OUTER JOIN tbl_ecom_shipping_service AS s ON prod.role = s.shs_id
WHERE (
    s.shs_id IS NULL
)
AND ( prod_1_.visible_on_website = 1 )

AND ( prod_1_.name LIKE ?
    OR prod.stock_code LIKE ?
    OR prod.supplier_part_number LIKE ?
)
AND ( prod_1_.name LIKE ?
    OR prod.stock_code LIKE ?
    OR prod.supplier_part_number LIKE ?
)
UNION
SELECT DISTINCT prod.prod_id as node1_76_0_, prod.stock_code as stock2_95_0_, prod.supplier_part_number as supplier3_95_0_, prod.sold_in_multiple as sold4_95_0_, prod.free as free95_0_, prod.poa as poa95_0_, prod.allow_back_order as allow7_95_0_, prod.stock_threshold as stock8_95_0_, prod.low_stock_threshold as low9_95_0_, prod.tax_type as tax10_95_0_, prod.nominal_sale as nominal11_95_0_, prod.nominal_purchase as nominal12_95_0_, prod.commodity_code as commodity13_95_0_, prod.preferred_alternative as preferred14_95_0_, prod.role as role95_0_, prod.stock_type as stock16_95_0_, prod.weight as weight95_0_, prod.imported_by as imported18_95_0_, prod.import_code as import19_95_0_, prod.customisable as customi20_95_0_, prod.customisable_prompt as customi21_95_0_, prod.agent_only as agent22_95_0_, prod.sell_to_retail as sell23_95_0_, prod.sell_to_trade as sell24_95_0_, prod.sell_by_decimal as sell25_95_0_, prod.length as length95_0_, prod.breadth as breadth95_0_, prod.width as width95_0_, prod.hazardous as hazardous95_0_, prod.fragile as fragile95_0_, prod.liquid as liquid95_0_, prod.palletised as palletised95_0_, prod.attractive as attractive95_0_, prod.boxed as boxed95_0_, prod.charge_code as charge35_95_0_, prod.discount_code as discount36_95_0_, prod.floor_price as floor37_95_0_, prod.cost_price as cost38_95_0_, prod.crm as crm95_0_, prod.category as category95_0_, prod.sub_category as sub41_95_0_, prod_1_.version_number as version2_76_0_, prod_1_.[name] as name3_76_0_, prod_1_.visible_on_website as visible4_76_0_, prod_1_.url_part as url5_76_0_, prod_1_.parent as parent76_0_, prod_1_.bnd_id as bnd7_76_0_, prod_1_.template as template76_0_, prod_1_.custom_string_1 as custom9_76_0_, prod_1_.custom_string_2 as custom10_76_0_, prod_1_.custom_string_3 as custom11_76_0_, prod_1_.custom_string_4 as custom12_76_0_, prod_1_.custom_string_5 as custom13_76_0_, prod_1_.custom_bool_1 as custom14_76_0_, prod_1_.custom_bool_2 as custom15_76_0_, prod_1_.custom_bool_3 as custom16_76_0_, prod_1_.custom_bool_4 as custom17_76_0_, prod_1_.custom_bool_5 as custom18_76_0_, prod_1_.custom_decimal_1 as custom19_76_0_, prod_1_.custom_decimal_2 as custom20_76_0_, prod_1_.custom_decimal_3 as custom21_76_0_, prod_1_.custom_decimal_4 as custom22_76_0_, prod_1_.custom_decimal_5 as custom23_76_0_, prod_1_.created as created76_0_, prod_1_.updated as updated76_0_, prod_1_.created_by as created26_76_0_, prod_1_.updated_by as updated27_76_0_, prod_1_.flags as flags76_0_, prod_1_.active as active76_0_
FROM tbl_ecom_cat_product prod
   INNER JOIN tbl_ecom_cat_node prod_1_ ON prod_1_.node_id = prod.prod_id
   LEFT OUTER JOIN tbl_ecom_cat_node_text nt ON prod.prod_id = nt.node_id
   LEFT OUTER JOIN tbl_ecom_shipping_service AS s ON prod.role = s.shs_id
WHERE (
    s.shs_id IS NULL
)
AND ( prod_1_.visible_on_website = 1 )

AND CONTAINS(nt.text, 'orbit gum', LANGUAGE 'English')
4

2 回答 2

1

因为你的 sql 变量是 null 没有实例化

您必须添加此代码

if(sql != null)
{
 ....
}

或在开始时创建此行

var sql = new StringBuilder();
于 2012-07-27T09:15:23.600 回答
1

这部分:

AND CONTAINS(nt.text, 'orbit gum', LANGUAGE 'English')
 ]
  Name: wildcard1 - Value: %gum%
  Name: wildcard0 - Value: %orbit%
[SQL: 

看起来完全错误。看起来调试代码由于某种原因混入了查询中?不知道是什么原因造成的。

于 2012-07-27T09:47:31.637 回答