2013-05-24 7 views
9

Sono in procinto di convertire alcune vecchie pagine PHP per utilizzare PDO."Il risultato attivo non contiene campi" utilizzando PDO con MS SQL

Qui di seguito sono due query semplificate (non le mie domande effettivi) per aiutare la comprensione del problema che sto avendo ...

SELECT afield INTO #temptable FROM atable WHERE anotherfield = 'somevalue'; 

SELECT afield,anotherfield,onemorefield FROM atable 
WHERE afield NOT IN (SELECT * FROM #temptable); 

La query sopra genera l'errore descritto nel titolo (in modo più completo getta "Fatal error: eccezione Uncaught 'PDOException' con il messaggio 'SQLSTATE [IMSSP]: il risultato attivo per la query contiene nessun campo.'")

Se io modificare la query come questo ...

with (SELECT afield INTO #temptable FROM atable 
WHERE anotherfield = 'somevalue') AS temptable; 

SELECT afield,anotherfield,onemorefield FROM atable 
where afield NOT IN (SELECT * FROM temptable); 

Questo sembra aggirare l'errore, ma questa versione della query è orribilmente orribilmente inefficiente perché sembra eseguire la query temptable per ogni singolo campo di confronto nell'altra query.

C'è un modo per far funzionare il primo modulo (che crea una tabella temporanea una volta) con PDO?

Ha funzionato bene nella vecchia pagina che utilizzava mssql.

EDIT: So che probabilmente si può fare questo in modo 'disordinato' con la creazione di un tavolo vero e proprio, eseguirlo in php, quindi eseguire la seconda query (in una chiamata php a parte), quindi eseguire una terza interrogazione lasciare il primo tavolo. Ma preferirei non dover ricorrere a quello! :)

+0

Si noti che le parole chiave SQL come "SELECT, WHERE, FROM ..." devono essere in maiuscolo. Ciò migliorerà la leggibilità. Dovresti iniziare con questo primo – hek2mgl

+0

Se insisti! . – MrVimes

+0

Separa effettivamente le query con un punto e virgola ';'? – hek2mgl

risposta

10

Il motore PDO vede questa query restituendo due set di risultati (il vecchio motore mssql probabilmente ha appena ignorato tutto tranne l'ultima query in una stringa di query generale). Sono riuscito a farlo funzionare saltando sopra il primo set di risultati (la tabella temporanea) utilizzando il seguente comando

$statement->nextRowset(); 

e quindi utilizzando $statement->fetch(); come normale

31

Se si utilizza una stored procedure quindi utilizzare

SET NOCOUNT ON 

Il problema è che la stored procedure restituisce un risultato contenente il numero di righe interessate come primo risultato.

Microsoft Documentation

1

Sto usando laravel5 e questo è come ho risolto il problema;

DB::select("SET ANSI_NULLS ON; SET ANSI_WARNINGS ON;EXEC [storedprocedure] $param1,$param2;"); 
+1

Grazie Kamaro. Sono su Laravel5 e questo mi ha aiutato. Ho eseguito 'DB :: select ('SET NOCOUNT ON; EXEC stored_procedure');' e ha funzionato perfettamente. –

0

Se si utilizza un StoredProcedure e fare qualcosa come:

DB::select("EXEC [storedprocedure] $param1,$param2;"); 

di quanto sopra, la PDO aspetta la dichiarazione DB::select per restituire alcuni dati. Ma se la vostra StoredProcedure non restituisce alcun dato, è possibile modificare DB::select PER DB::update come belows:

DB::update("EXEC [storedprocedure] $param1,$param2;"); 

Dopo questo dovrebbe apparire più l'errore.

2

mi sono imbattuto in questo problema e le risposte di cui sopra ha aiutato, ma le risposte qui assumo le cose:

  1. Si ha accesso alla modfy lo sProc con SET NOCOUNT ON e si vuole fare questo
  2. Sei sicuro è necessario passare alla prossima set di righe $statement->nextRowset();

Nel mio caso sto usando un metodo generico per tirare indietro i dati di più sprocs dove può o non può avere questo i ssue e necessario controllare prima di incrementare il set di righe.

ho usato il seguente:

while($stmt->columnCount() === 0 && $stmt->nextRowset()) { 
    // Advance rowset until we get to a rowset with data 
} 

if($stmt->columnCount() > 0) { 
    // We found something with data, do stuff. 
    // Code here 
} 

Speriamo che questo aiuta qualcun altro in esecuzione in un problema simile.