MSSQL2008 – Pyodbc – SQL anterior no era una consulta

No puedo entender qué está mal con el siguiente código, la syntax es correcta (verificada con SQL Management Studio), tengo acceso como debería, así que también funciona … pero por alguna razón, tan pronto como bash crear una tabla A través de PyODBC entonces deja de funcionar.

import pyodbc def SQL(QUERY, target = '...', DB = '...'): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + target + DB+';UID=user;PWD=pass') cursor = cnxn.cursor() cursor.execute(QUERY) cpn = [] for row in cursor: cpn.append(row) return cpn print SQL("CREATE TABLE dbo.Approvals (ID SMALLINT NOT NULL IDENTITY PRIMARY KEY, HostName char(120));") 

Falla con:

 Traceback (most recent call last): File "test_sql.py", line 25, in  print SQL("CREATE TABLE dbo.Approvals (ID SMALLINT NOT NULL IDENTITY PRIMARY KEY, HostName char(120));") File "test_sql.py", line 20, in SQL for row in cursor: pyodbc.ProgrammingError: No results. Previous SQL was not a query. 

¿Alguien tiene alguna idea de por qué esto es? Tengo un controlador “SQL Server” instalado (es el predeterminado), ejecutando Windows 7 en un entorno Windows 2008 SQL Server (no es una base de datos expresa).

En caso de que algún nómada neto solitario se encuentre con este problema, la solución de Torxed no funcionó para mí. Pero lo siguiente me funcionó.

Estaba llamando a un SP que inserta algunos valores en una tabla y luego devuelve algunos datos. Solo agregue lo siguiente al SP:

 SET NOCOUNT ON 

Funcionará bien 🙂

El código de Python:

  query = "exec dbo.get_process_id " + str(provider_id) + ", 0" cursor.execute(query) row = cursor.fetchone() process_id = row[0] 

El SP :

 USE [DBNAME] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure [dbo].[GET_PROCESS_ID]( @PROVIDER_ID INT, @PROCESS_ID INT OUTPUT ) AS BEGIN SET NOCOUNT ON INSERT INTO processes(provider_id) values(@PROVIDER_ID) SET @PROCESS_ID= SCOPE_IDENTITY() SELECT @PROCESS_ID AS PROCESS_ID END 

Obtuve esto porque estaba reutilizando un cursor sobre el que estaba haciendo un bucle:

 rows = cursor.execute(...) for row in rows: # run query that returns nothing cursor.execute(...) # next iteration of this loop will throw 'Previous SQL' error when it tries to fetch next row because we re-used the cursor with a query that returned nothing 

Utilice 2 cursores diferentes en su lugar

 rows = cursor1.execute(...) for row in rows: cursor2.execute(...) 

u obtenga todos los resultados del primer cursor antes de usarlo nuevamente:

Utilice 2 cursores diferentes en su lugar

 rows = cursor.execute(...) for row in list(rows): cursor.execute(...) 

Como cubren otros, SET NOCOUNT ON se ocupará de los conjuntos de resultados adicionales dentro de un procedimiento almacenado, sin embargo, otras cosas también pueden causar una salida adicional que NOCOUNT no evitará (y pyodbc verá como un conjunto de resultados), como olvidarse de eliminar una statement de impresión después de la depuración su procedimiento almacenado

Antes que nada:

Si está ejecutando un Windows SQL Server 2008, use el “Cliente nativo” que se incluye con la instalación del software SQL (se instala con la base de datos y los Kits de herramientas, por lo que necesita instalar la aplicación SQL Management de Microsoft)

En segundo lugar: use “Trusted_Connection = yes” en su statement de conexión de SQL:

 cnxn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};SERVER=ServerAddress;DATABASE=my_db;Trusted_Connection=yes') 

¡Esto debería funcionar!

En caso de que su SQL no esté almacenado Proc.

el uso de ‘xyz! = NULL’ en la consulta, dará el mismo error, es decir, “pyodbc.ProgrammingError: No hay resultados. SQL anterior no era una consulta”.

Use ‘no es nulo’ en su lugar.