c# - simple - escribir comillas en vb
Escape de comillas dobles en SQL 2005/2008 (8)
¿Has intentado sustituir al personaje con su código ASCII?
Tengo una compañía internacional que se ha agregado recientemente, que se llama "BLA" BLAHBLAH "Ltd. (Las comillas dobles son parte del nombre).
Cada vez que un usuario intenta buscar esta empresa, al ingresar "Blah" o algo así, la búsqueda falla con un error de sintaxis en el servidor SQL.
¿Cómo puedo escapar de esto para que la búsqueda no falle?
Ejemplo de SQL:
SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
FROM RussoundGeneral.dbo.Company c
LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
ON (cm.companyId = c.companyId and cm.maxID is not null)
WHERE CONTAINS ( companyName, ''"BLAH*'' )
GROUP BY c.companyID, c.companyName, c.dateAdded
ORDER BY c.companyName ASC
Desafortunadamente, las comillas dobles tienen un significado especial dentro de FTI, por lo tanto, incluso si lo parametriza, el motor FTI lo trata como un delimitador de frase. No estoy seguro de que haya una manera fácil de incluir comillas dobles en una búsqueda FTI. Los corchetes también son un carácter especial, pero pueden incluirse entre comillas para tratar como un término de consulta, pero no como comillas dobles AFAIK.
Actualizar
Un poco de búsqueda sugiere que doblar la cita a "" puede solucionarlo, vale la pena intentarlo. Personalmente, haría esto dentro de la base de datos, ya que este es un detalle de implementación de TSQL.
Del mismo modo, ''se debe doblar a'' ''antes de pasar a FTI (completamente separado del escape de TSQL),
Esta es una respuesta teórica, pero quizás ayude. La versión corta es "usar parámetros en la consulta", pero ayuda a comprender todos los detalles.
En SQL estándar, las cadenas están entre comillas simples, y las comillas simples incrustadas están representadas por dos comillas simples en una fila:
SELECT * FROM SomeWhere
WHERE SomeThing = ''He said, "Don''''t do it!"'';
En algunos dialectos de SQL, en su lugar puede cerrar cadenas de caracteres entre comillas dobles; luego debe duplicar las comillas dobles para incrustar una sola instancia de una comilla doble:
SELECT * FROM SomeWhere
WHERE SomeThing = "He said, ""Don''t do it!""'';
No queda claro a partir de la pregunta si el nombre de la empresa incluye las comillas dobles exteriores, así como la del medio, o si solo contiene la del medio. Sin embargo, en principio, las reglas son las mismas. Suponiendo que se requieren las tres comillas dobles, y usando comillas simples en el SQL, es mucho más fácil en este contexto:
SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
FROM RussoundGeneral.dbo.Company c
LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
ON (cm.companyId = c.companyId and cm.maxID is not null)
WHERE CONTAINS ( companyName, ''"BLAH "BLAHBLAH" Ltd.'' )
GROUP BY c.companyID, c.companyName, c.dateAdded
ORDER BY c.companyName ASC;
Usando comillas dobles:
SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
FROM RussoundGeneral.dbo.Company c
LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
ON (cm.companyId = c.companyId and cm.maxID is not null)
WHERE CONTAINS ( companyName, """BLAH ""BLAHBLAH"" Ltd." )
GROUP BY c.companyID, c.companyName, c.dateAdded
ORDER BY c.companyName ASC;
Si está creando cadenas en un lenguaje de programación, entonces debe preocuparse de obtener estas citas más allá de lo que evalúe las cadenas en su lenguaje de programación. Por ejemplo, si estuvieras construyendo un literal de cadena en C, tendrías que escapar de las comillas dobles con barras diagonales inversas:
static const char sql_stmt[] =
"SELECT c.companyID, c.companyName, c.dateAdded,/n"
" COUNT(cm.maxID) AS NumDirect/n"
" FROM RussoundGeneral.dbo.Company c/n"
" LEFT JOIN RussoundGeneral.dbo.CompanyMax cm/n"
" ON (cm.companyId = c.companyId AND cm.maxID IS NOT NULL)/n"
" WHERE CONTAINS(companyName, /"/"/"BLAH /"/"BLAHBLAH/"/" Ltd./")/n"
" GROUP BY c.companyID, c.companyName, c.dateAdded/n"
" ORDER BY c.companyName ASC";
Por otro lado, si lees los datos del usuario, como el nombre de la empresa, entonces simplemente debes asegurarte de que lo que se lee se cita correctamente.
Aquellos que dijeron "usar parámetros" son correctos, es mucho más fácil y más confiable y menos vulnerable a los ataques de inyección SQL (consulte XKCD si aún no lo ha visto). Pero si comprende los fundamentos, puede adaptarse a los requisitos reales de su sistema.
Nota final: en SQL estándar, las comillas dobles encierran ''identificadores delimitados''. Es decir, las comillas dobles rodean un nombre que debe tratarse como el nombre de algo en la base de datos, no como un literal de cadena. En MS SQL Server, los [corchetes] sirven para el mismo propósito; lo que está entre los corchetes es el nombre de una columna o lo que sea dentro de la base de datos. Muchos sistemas son más flexibles que eso; no todos los sistemas son iguales en la forma en que se desvían del estándar.
Pruebe usar la palabra clave escape
SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
FROM RussoundGeneral.dbo.Company c
LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
ON (cm.companyId = c.companyId and cm.maxID is not null )
WHERE CONTAINS ( companyName, ''/"BLAH*'' ) escape ''/'
group by c.companyID, c.companyName, c.dateAdded ORDER BY c.companyName ASC
Use una consulta parametrizada y todos sus problemas de cotización habrán desaparecido.
Editar: si no les permite ingresar más de una palabra en CONTIENE, desinfecte el parámetro quitando las comillas. Desinfectar la entrada eliminando las comillas puede funcionar de todos modos, independientemente de la búsqueda de varias palabras.
debería ser algo así como
string sqlCommand = "SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect FROM RussoundGeneral.dbo.Company c LEFT JOIN RussoundGeneral.dbo.CompanyMax cm ON (cm.companyId = c.companyId and cm.maxID is not null ) WHERE CONTAINS ( companyName, ''@strVal'' ) group by c.companyID, c.companyName, c.dateAdded ORDER BY c.companyName ASC"
SqlCommand command = new SqlCommand(strSQLCommand, conn);
SqlCommand.Parameters.AddWithValue("@strval", SearchTextBox.Text);
Finalmente tendrá que extraer datos de su base de datos y hacer que se muestren en la pantalla o se impriman en informes. Manipular comillas dobles o cualquier personaje extra puede ser muy confuso.
Al convertir sus cadenas a HTML antes de INSERTS o UPDATES, está evitando toda la confusión relacionada con la gestión de presupuestos. En el momento de SELECCIONAR, será fácil convertir de nuevo desde HTML. En el momento del informe (como las herramientas de informes (como Crystal Reports) proponen una opción de formato HTML), ni siquiera tendrá que hacer nada para mostrar los datos de forma correcta.
Por cierto, no te olvides de colgar al tipo que inventó el nombre de esta empresa.
Sospecho que estás construyendo SQL de forma dinámica, por ejemplo
// Bad code, do not use!
string sql = "SELECT * FROM Foo WHERE X LIKE ''" + input + "%''";
Esa es una idea realmente mala por muchas razones, especialmente los ataques de inyección SQL . Use en su lugar sentencias SQL parametrizadas, donde especifica los parámetros por separado.
Vea varias respuestas a las preguntas con la etiqueta sql-injection para ver ejemplos de cómo hacer esto correctamente.