2009-08-31 9 views
11

he construido una consulta T-SQL como esto:Las preocupaciones sobre SQL Server 2008 Texto completo Búsqueda

DECLARE @search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)' 

SELECT * FROM Tickets 
WHERE ID IN (
       -- unioned subqueries using CONTAINSTABLE 
          ... 
      ) 

La interfaz gráfica de usuario para esta búsqueda serán una página aspx con un único cuadro de texto donde el usuario puede buscar.

Planeo construir de alguna manera el término de búsqueda para que sea como el ejemplo anterior (@search).

tengo algunas preocupaciones, sin embargo:

  • es el ejemplo término de búsqueda por encima de la mejor o la única manera de incluir las inflexiones de todas las palabras en la búsqueda?
  • Debo separar las palabras y construir el término de búsqueda en C# o T-SQL. Tiendo a inclinarme hacia C# para decisiones/bucle/construcción, pero quiero tu opinión.
  • Odio construir SQL dinámicamente debido al riesgo de inyección. ¿Cómo puedo protegerme de esto?
  • ¿Debo usar FREETEXTTABLE en su lugar? ¿Hay alguna manera de hacer que FREETEXT busque TODAS las palabras en lugar de CUALQUIER?
  • En general, ¿de qué otro modo haría esto?

Respuesta

3

Recientemente utilicé Búsqueda de texto completo, así que intentaré responder algunas de sus preguntas.

• "Odio construir sql dinámicamente debido al riesgo de inyección. ¿Cómo puedo evitar esto?"

que utiliza un método de higienización como esto:

static string SanitizeInput(string searchPhrase) 
    { 
     if (searchPhrase.Length > 200) 
      searchPhrase = searchPhrase.Substring(0, 200); 

     searchPhrase = searchPhrase.Replace(";", " "); 
     searchPhrase = searchPhrase.Replace("'", " "); 
     searchPhrase = searchPhrase.Replace("--", " "); 
     searchPhrase = searchPhrase.Replace("/*", " "); 
     searchPhrase = searchPhrase.Replace("*/", " "); 
     searchPhrase = searchPhrase.Replace("xp_", " "); 

     return searchPhrase; 
    } 

• ¿Debo usar FREETEXTTABLE en su lugar? ¿Hay alguna manera de hacer que FREETEXT busque TODAS las palabras en lugar de CUALQUIER?

Utilicé FREETEXTTABLE, pero necesitaba alguna de las palabras. Por mucho que lo haya leído (y he leído bastante), debe usar CONTAINSTABLE para buscar TODAS las palabras o diferentes combinaciones. FREETEXTTABLE parece ser la solución más liviana, pero no la que elegir cuando se desean personalizaciones más profundas.

0

En su ejemplo, tiene la variable @search ya definida. Como regla general, no debe incluir texto concatenado dinámicamente en SQL sin procesar, debido al riesgo de inyección. Sin embargo, puede establecer el valor de @search en el objeto de comando de llamada desde su aplicación. Esto niega por completo el riesgo de ataques de inyección.

Recomendaría la construcción del término de búsqueda en C#; pasando el término de búsqueda final en un parámetro como el ya mencionado.

Por lo que recuerdo, FREETEXTTABLE utiliza separadores de palabras para descomponer por completo los términos de búsqueda en sus componentes individuales. Sin embargo, el operador FREETEXTTABLE descompone automáticamente las palabras en inflectional equivalent también, por lo que no tendrá que construir un operador complejo CONTAINSTABLE si decide usarlo.

Puede INNER JOIN los resultados de múltiples consultas para producir un resultado equivalente AND.

2

Dan, me gusta su método SanitizeInput.Lo rediseñé para hacerlo más compacto y mejorar el rendimiento un poco.

static string SanitizeInput(string searchPhrase, int maxLength) 
     { 
      Regex r = new Regex(@";|'|--|xp_|/\*|\*/", RegexOptions.Compiled); 
      return r.Replace(searchPhrase.Substring(0, searchPhrase.Length > maxLength ? maxLength : searchPhrase.Length), " "); 
     } 

     static string SanitizeInput(string searchPhrase) 
     { 
      const int MAX_SEARCH_PHRASE_LENGTH = 200; 
      return SanitizeInput(searchPhrase, MAX_SEARCH_PHRASE_LENGTH); 
     } 

Acepto que FreeTextTable es una solución demasiado liviana.

0

Todas nuestras búsquedas están en columnas en la base de datos que tienen caracteres válidos predefinidos. Nuestro algoritmo de búsqueda incorpora esto con una expresión regular que solo permite estos caracteres predefinidos. Debido a esto, no es necesario escapar en la cadena de búsqueda. Nuestra expresión regular elimina cualquier intento de inyección en el código web (asp & aspx). Para los comentarios estándar de los usuarios, usamos escaping que cambia todos los caracteres que pueden usarse para dañar en SQL, ASP, ASPX, & Javascript.
El sitio de TransStar http://latranstar.tann.com/ está utilizando una forma extendida de Soundex para buscar nombres de calles, direcciones y ciudades en cualquier parte del sur de California. El Soundex por sí mismo elimina la necesidad de un código antiinyección, ya que solo funciona con caracteres alfabéticos.

Cuestiones relacionadas