conectar - python sql connection
MSSQL2008-Pyodbc-SQL anterior no era una consulta (5)
No puedo entender qué está mal con el siguiente código, la sintaxis 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 intento 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 <module>
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).
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 declaración de conexión SQL:
cnxn = pyodbc.connect(''DRIVER={SQL Server Native Client 10.0};SERVER=ServerAddress;DATABASE=my_db;Trusted_Connection=yes'')
¡Esto debería funcionar!
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 olvidar eliminar una declaración de impresión después de la depuración su procedimiento almacenado
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 funcionó para mí.
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
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.
Lo obtuve 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(...)