2009-08-12 9 views
6

que quiero usar una consulta de la siguiente manera, estoy buscando para obtener información exacta/enlace para escapar de las cadenascadena correcta de escape por los literales de cadena T-SQL

BOOKTITLE es de tipo nvarchar (200)

SELECT * FROM Libros DONDE BookTitle IN ('Mars and Venus', 'Overflow' de la pila \ r \ n ')

Pregunta: ¿Solo se debe "escapar" o incluso se debe escapar \ r \ n? ? MySql .Net Provider expone un método para escapar de los valores de cadena, ¿existe alguna función en el servidor Sql .Net Provider?

Probablemente necesite un escape de C# equivalente para los valores de cadena.

Conozco el Comando parametrizado, pero para minimizar la comunicación entre el servidor y el cliente, y mis valores en la cláusula IN están en el número de 20 a 50, se vuelve demasiado costoso para ejecutar SELECT para cada valor de BookTitle en una llamada En lugar de ejecutar una sola consulta y devolver todos los resultados en cascada, ayuda a ahorrar recursos de red.

+0

Este es un comentario tangencial, pero sigue siendo importante. Si haces esto para tus propias consultas en el estudio de administración, está bien. Pero si está haciendo _programmatically_ — construyendo su cadena de consulta y escapando en un programa del lado del cliente — _lo está haciendo mal_. Necesitas una consulta parametrizada. –

+0

Su sugerencia de que necesite ejecutar 1 selección para cada valor del parámetro es incorrecta. Utilice un parámetro con valores de tabla OR XML O utilice una cadena delimitada por comas y descomprímalo en el lado del servidor SQL. Esa será una consulta. http://www.sommarskog.se/arrays-in-sql-2008.html – Davos

Respuesta

2

hay más cosas que tienen que ser escapado de sólo comillas o caracteres de nueva línea. ¿Qué pasa si hay una entrada binaria (por hacker)? Es mejor usar PreparedStatement (en java) o cualquier otro equivalente en el idioma de destino. Ejemplo de Java:

PreparedStatement ps = con.prepareStatement("SELECT * FROM Books WHERE BookTitle IN (?, ?)"); 
ps.setString(1, "Mars and Venus"); 
ps.setString(2, "Stack's Overflow 
and 
"); 

ResultSet rs = ps.executeQuery(); 
.... 
+0

Aunque esta no es una respuesta completa, pero sí, intenté algo similar en C# con una pequeña solución y es aceptable por ahora. –

5

SQL Server no reconocerá la secuencia \r\n, ya sea que se haya escapado o no.

Tendrá que hacer algo como esto en su lugar si desea hacer coincidir la \r\n en BookTitle:

-- \r = CHAR(13) 
-- \n = CHAR(10) 
SELECT * 
FROM Books 
WHERE BookTitle IN ('Mars and Venus', 'Stack''s Overflow ' + CHAR(13) + CHAR(10)) 
+0

Sí, lo entiendo, pero tengo que hacer esto en C# de forma dinámica para cada tipo, como si necesitara una secuencia de escape que pueda usar una cadena. .replace para todos esos valores y prepare la consulta final. –

+0

En ese caso, no use cadena de escape. Use una consulta parametrizada en su lugar. – LukeH

0

Puede usar los parámetros de valores de tabla para pasar los valores de su instrucción IN. Si no está utilizando una versión lo suficientemente nueva de Visual Studio y/o SQL Server para tener acceso a los parámetros de valor de la tabla, puede pasar una lista separada por comas como parámetro de cadena, y luego analizar el parámetro en una tabla. Hay varios métodos para dividir cadenas en una tabla/variable de tabla variable. Puede googlear "función de división en el servidor SQL" para obtener varias opciones.

0

Por lo general, lo que haría para situaciones como ésta, es pasar su información como un parámetro, pero en XML, por lo que se puede hacer algo como esto:

DECLARE @iDoc INT 
EXEC sp_xml_preparedocument @iDoc OUTPUT, @MyXml 

SELECT 
    * 
FROM 
    MyTable 
WHERE 
    MyColumn IN (SELECT [Id] FROM OPENXML(@iDoc,'/ss/s',2) WITH ([Id] INT '.')) 

EXEC sp_xml_removedocument @iDoc 

en este caso, el código XML haría parecer '<ss><s>1</s><s>2</s>...etc...</ss>'

+0

Un CRLF no sobreviviría al procesamiento xml, ¿o sí? Como se trata como espacio en blanco, tendrías que escapar de alguna manera. ¿Cómo se puede escapar un CRLF en Xml de todos modos? Supongo que con CDATA, pero ¿cómo se jugaría eso en la consulta? – Cyberherbalist

+0

No creo que los espacios en blanco en general deban escaparse en XML; es solo lo que es – John

2

Me encontré con un problema similar, donde necesitaba tener una IN en mi consulta de selección, y la cantidad de elementos variaba en tiempo de ejecución.

Utilizo una consulta parametrizada en forma de procedimiento almacenado y paso una cadena delimitada que contiene la lista de cosas que estoy buscando. El sistema maneja automáticamente el escape, sin necesidad de tomar medidas extraordinarias. Mejor no hacerlo delimitado por caracteres que se encontrarán en el texto que está buscando (como comas). una barra vertical ("|") probablemente funcionaría mejor en muchos casos.

Por cierto, asegúrese de que los CRLF en su tabla sean CHAR (13) + CHAR (10) porque al revés no está \ r \ n y no lo encontraría si Environment.NewLine fuera parte de tu búsqueda.

Aquí es un procedimiento almacenado mediante un análisis sintáctico rápido y sucio resolver a una tabla que he utilizado:

CREATE PROCEDURE FindBooks 
(
    @list varchar(500) 
) 
AS 

CREATE TABLE #parse_table (item varchar(500)) 

DECLARE @temp      VARCHAR(500) 
DECLARE @result      VARCHAR(500) 
DECLARE @str      VARCHAR(500) 
DECLARE @pos      SMALLINT 

SET @temp = RTRIM(LTRIM(@list)) 
SET @pos = 1 

WHILE @pos > 0 
    BEGIN 
    SET @pos = CHARINDEX('|',@temp) 
    IF @pos > 0 
     BEGIN 
     SET @result = SUBSTRING(@temp,1,@pos - 1) 
     SET @temp = RTRIM(LTRIM(SUBSTRING(@temp,@pos+1,LEN(@temp) - @pos))) 

     INSERT INTO #parse_table 
    SELECT @result 
     END 
    ELSE 
     INSERT INTO #parse_table 
     SELECT @temp 
END 

SELECT * FROM Books WHERE Title in (select * from #parse_table) 

Basta con crear su lista de títulos de libros en forma de cadena sencilla (que contiene todo lo apóstrofes incrustadas, CRLFs, y etc.) y utiliza una consulta parametrizada. Por supuesto, su proceso almacenado puede contener otras cosas además de la lista delimitada.

Cuestiones relacionadas