2009-07-01 10 views
7

Per eaxmple, LINQ to SQL sta inviando il seguente:Perché LINQ invia sp_executesql invece di eseguire direttamente l'SQL?

exec sp_executesql 
N'SELECT [t0].[HomeID], 
    [t0].[Bedrooms], 
    [t0].[ImageURL], 
    [t0].[Price], 
    [t0].[Available], 
    [t0].[Description] 
FROM 
    [dbo].[Homes] AS [t0] 
WHERE 
    ([t0].[Description] LIKE @p0) AND 
    ([t0].[Available] = @p1) AND 
    ([t0].[Price] >= @p2) AND ([t0].[Price] <= @p3) 
ORDER BY 
    [t0].[Price] DESC', 
N'@p0 nvarchar(4000),@p1 int,@p2 int,@p3 int', 
@p0=N'%private%', 
@p1=1, 
@p2=200000, 
@p3=750000 

Perché si utilizza sp_executesql?

+0

OP, dovresti chiarire cosa intendi un po '- lo prendo guardando attraverso SQL Profiler e vedi le chiamate che scorrono. Interpreto la tua domanda come "perché L2S usa sp_executesql piuttosto che inviare direttamente le istruzioni contenute". – stephbu

risposta

11

Questa notazione consente di riutilizzare l'istruzione TSQL compilata in runtime con parametri diversi; cioè la dichiarazione viene compilata solo una volta che migliora l'efficienza.

+1

Execute utilizza la stessa cache dell'istruzione con query parametrizzate. – stephbu

+1

Inoltre, in questo modo è più sicuro contro l'iniezione SQL. – gerleim

4

EDIT, oops Ho detto paramterization invece di sostituzione parametro, grazie stephbu

sp_executesql è preferito eseguire perché supporta sostituzione di parametro, e tende ad eseguire in modo più efficiente.

+1

Execute è parametrizzabile, quindi la parametrizzazione non è così. Quali dati dice che esegue "in modo più efficiente" Almeno lo stesso costo. – stephbu

+0

Potrebbe essere stato tecnicamente più corretto dire sostituzione di parametro piuttosto che parametrizzazione, in quanto per l'efficienza vi invito a controllare il seguente link. http://msdn.microsoft.com/en-us/library/ms175170.aspx – cmsjr

+0

http://msdn.microsoft.com/en-us/library/ms175580.aspx come informazioni aggiuntive su Esecuzione supportando la stessa memorizzazione di istruzioni con parametri strategie. – stephbu

4

Questo è, almeno in parte, in modo da ottenere il riutilizzo del piano di query. Potrebbe mettere i parametri in linea, il che significa che ogni volta che si esegue la query con parametri diversi, l'analizzatore la vede come una query diversa e la ripara. Ma dal momento che viene eseguito in questo modo, il piano di query viene memorizzato nella cache e può semplicemente collegare le nuove variabili ogni volta che viene eseguito.

0

Una cosa da notare è che fornisce anche protezione da SQL Injection a causa della parametrizzazione. Non posso davvero lamentarmi di quello ...

+0

Non in base a questo link: http://msdn.microsoft.com/en-us/library/ms188001.aspx - "Le istruzioni Transact-SQL di esecuzione del tempo compilate possono esporre le applicazioni a attacchi dannosi, come l'iniezione SQL." – Adamski

+0

Questo non è un motivo per utilizzare sp_executesql tho '. La parametrizzazione è disponibile anche per le chiamate SqlExecDirect tramite OLE/DB e ODBC. – stephbu

+0

@Adamski - ovviamente lo fa ... http://msdn.microsoft.com/en-us/library/bb386929.aspx. "LINQ to SQL evita tale iniezione utilizzando SqlParameter nelle query." – jinsungy

0

Questa è una bella domanda.
Questa non è una vera risposta, ma un'esplorazione del ragionamento già dato da altre risposte. Sentitevi liberi di aggiornare questa "risposta"

La risposta ovvia sarebbe stata "parameterized query cache". Tuttavia, i parametri potrebbero essere facilmente associati quando la dichiarazione è stata eseguita direttamente e ancora memorizzati nella cache.

Sintassi e dettagli in questo MSDN articolo ...

msdn_microsoft_ms175580

prestazioni dichiarate dubito senza dati dal momento che la cache sembra essere lo stesso per entrambe le query dirette e sp_execsql'd.

Quindi se non sono quelli - che cos'è?

2

Non penso che sia una soluzione per le prestazioni. I piani di esecuzione in SQL sono memorizzati nella cache anche per le query dirette.

Penso che sia una soluzione di sicurezza per l'iniezione sql.

Tuttavia, se si tenta di utilizzare tracce che utilizzano Linq su SQL nell'Assistente ottimizzazione motore di database, sp_execute non viene interpretato da Ottimizzazione guidata, vorrei disattivarlo. SQL injection può anche essere rilevato nelle istruzioni/framework Linq To Sql (il codice) perché dovresti provare a inviare dati non validi a SQL.

Problemi correlati