Question

I am currently using Irony as part of my searching system and I have had countless problems regarding incorrect syntax which I have massively managed to narrow down but now I am stuck on my last issue that appears to be with certain keywords.

If you were to search anything that contains "or" or "and" followed by anything it returns a Syntax error in the SQL seach string.

With other issues I have just simply escaped rogue characters or simply removed them completely from the search, however this does not seem to be a viable solution to this as these words could be a bit part of our search.

Link to 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>();

It is when the union is added to the string that it causes it to freak out and throw the error and the error appears on the last line.

The actual error is:

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'.

How the other issues are currently resolved;

    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.

The actual query when giving the error is:

    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')
Was it helpful?

Solution

This part:

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

Looks completely wrong. It looks like debugging code was mixed into the query for some reason? No idea what causes it though.

OTHER TIPS

Because your sql variable is null not instanciated

you must add this code

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

Or create this line in the begin

var sql = new StringBuilder();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top