2009-08-12 15 views
6

che voglio utilizzare una query come seguendo, Cerco informazioni esatte/link per sfuggire stringhestringa corretta Escaping per stringhe letterali T-SQL

BOOKTITLE è NVARCHAR (200)

SELECT * FROM Books DOVE BookTitle IN ('Mars and Venus', 'Stack''s Overflow \ r \ n ')

Domanda: Solo "" deve essere scappato o anche \ r \ n deve essere scappato pure ? MySql .Net Provider espone un metodo per l'escape dei valori di stringa, esiste una tale funzione nel provider .Net di Sql Server?

Probabilmente ho bisogno di eseguire l'escape equivalente in C# per i valori stringa.

Sono a conoscenza di Parameterized Command, ma al fine di ridurre al minimo il mio server alla comunicazione client ei miei valori nella clausola IN sono in numero da 20 a 50, diventa troppo costoso per eseguire SELECTs per ogni valore di BookTitle in una sola chiamata. Piuttosto, l'esecuzione di una singola query e il ripristino di tutti i risultati in cascata consente di risparmiare risorse di rete.

+0

Questo è un commento tangenziale, ma comunque importante. Se stai facendo questo per le tue query nello studio di gestione, va bene. Ma se stai facendo questo _programmaticamente_ — costruisci la tua stringa di query ed esegui l'escape in un programma lato client — _lo stai facendo male_. Hai bisogno di una query parametrizzata. –

+0

Il suggerimento che è necessario eseguire 1 selezione per ogni valore del parametro non è corretto. Utilizzare un parametro con valore di tabella O XML OPPURE utilizzare una stringa delimitata da virgole e decomprimerla sul lato di SQL Server. Questa sarà una domanda. http://www.sommarskog.se/arrays-in-sql-2008.html – Davos

risposta

2

ci sono più cose che devono essere sfuggito che appena virgolette o caratteri di nuova riga. Cosa succede se c'è un input binario (da parte di un hacker)? Meglio usare PreparedStatement (in java) o qualsiasi altro equivalente nella lingua di destinazione. Esempio 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

Anche se questa risposta non è completa, ma sì ho provato qualcosa di simile in C# con poca soluzione ed è accettabile per ora. –

5

SQL Server non riconoscerà la sequenza \r\n, sia che sia sfuggita o meno.

Avrai bisogno di fare qualcosa di simile, invece, se si vuole abbinare il \r\n in 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 prendo, ma ho bisogno di farlo in C# in modo dinamico per ogni tipo, come se avessi bisogno di una sequenza di escape che possa usare la stringa .sostituisce tutti questi valori e prepara la query finale. –

+0

In tal caso, non utilizzare l'escaping di stringhe. Utilizzare invece una query parametrizzata. – LukeH

0

È possibile utilizzare i parametri del valore di tabella per passare i valori dell'istruzione IN. Se non si utilizza una nuova versione di Visual Studio e/o SQL Server per accedere ai parametri del valore della tabella, è possibile passare in un elenco separato da virgole come parametro stringa e quindi analizzare il parametro in una tabella. Esistono diversi metodi per dividere le stringhe in una variabile tabella/tabella temporanea. Puoi google "split function in sql server" per diverse opzioni.

0

Di solito cosa farei per situazioni come questa, è passare le informazioni in come parametro, ma in XML, in modo da poter fare qualcosa di simile:

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 

in questo caso, il codice XML sarebbe assomigliare a '<ss><s>1</s><s>2</s>...etc...</ss>'

+0

Un CRLF non sarebbe sopravvissuto all'elaborazione xml, vero? Dato che è trattato come spazio bianco, dovresti fuggire in qualche modo. Come fai a fuggire da un CRLF in Xml? Immagino con CDATA, ma come si risolverebbe nella query? – Cyberherbalist

+0

Non credo che gli spazi in generale debbano essere sfuggiti in XML; è solo quello che è – John

2

Ho incontrato un problema simile, in cui avevo bisogno di avere un IN nella mia query di selezione, e il numero di elementi variava in fase di esecuzione.

Uso una query con parametri sotto forma di una stored procedure e passaggio in una stringa delimitata contenente l'elenco di cose che sto cercando. L'escaping viene gestito automaticamente dal sistema, senza necessità di compiere passi straordinari. Meglio non renderlo delimitato da caratteri che saranno trovati nel testo che stai cercando (come le virgole). una barra verticale ("|") probabilmente funzionerebbe meglio in molti casi.

A proposito, assicurati che i CRLF nella tua tabella siano CHAR (13) + CHAR (10) perché il modo opposto non è \ r \ n e non lo troverai se Environment.NewLine fosse parte della tua ricerca.

Ecco una stored procedure utilizzando un parse rapido e sporco risolvere a una tabella che ho usato:

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) 

sufficiente creare la tua lista di titoli di libri come una semplice stringa (contenente qualunque apostrofi incorporati, CRLFs, e così via) e utilizzare una query parametrizzata. Naturalmente, il tuo proc memorizzato può contenere altre cose oltre all'elenco delimitato.

Problemi correlati