Mssql2008-Pyodbc-SQL précédent N'était pas une requête
Je n'arrive pas à comprendre ce qui ne va pas avec le code suivant, La syntaxe est ok (vérifié avec SQL Management Studio), j'ai accès comme je le devrais pour que cela fonctionne aussi.. mais pour une raison quelconque dès que j'essaie de créer une table via PyODBC alors il cesse de fonctionner.
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));")
Il ne fonctionne pas avec:
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.
Quelqu'un sait pourquoi? J'ai installé un pilote" SQL Server " (il est par défaut), tournant Windows 7 contre un environnement Windows 2008 SQL Server (pas un express la base de données).
5 réponses
juste au cas où un nomade solitaire de net tombe sur ce problème, la solution de Torxed n'a pas fonctionné pour moi. Mais ce qui suit a fonctionné pour moi.
j'appelais un SP qui insère des valeurs dans une table puis renvoie des données. Il suffit d'ajouter ce qui suit au SP :
SET NOCOUNT ON
Cela fonctionnera parfaitement :)
le code Python:
query = "exec dbo.get_process_id " + str(provider_id) + ", 0"
cursor.execute(query)
row = cursor.fetchone()
process_id = row[0]
The 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
Comme les autres, SET NOCOUNT ON
va s'occuper des jeux de résultats supplémentaires à l'intérieur d'une procédure stockée, mais d'autres choses peuvent aussi causer des sorties supplémentaires que NOCOUNT n'empêchera pas (et pyodbc verra comme un jeu de résultats) comme l'oubli de supprimer une instruction d'impression après le débogage de votre procédure stockée.
j'ai eu ça parce que je réutilisais un curseur que j'étais en train de boucler:
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
Utilisez 2 curseurs différents à la place
rows = cursor1.execute(...)
for row in rows:
cursor2.execute(...)
ou obtenir tous les résultats de la première curseur avant de l'utiliser de nouveau:
Utilisez 2 curseurs différents à la place
rows = cursor.execute(...)
for row in list(rows):
cursor.execute(...)
tout d'Abord:
si vous utilisez un serveur Windows SQL 2008, utilisez le "Client natif" qui est inclus avec l'installation du logiciel SQL (il est installé avec la base de données et les boîtes à outils de sorte que vous devez installer L'application de gestion SQL de Microsoft)
d'autre part: Utilisez "Trusted_Connection=yes" dans votre déclaration de connexion SQL:
cnxn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};SERVER=ServerAddress;DATABASE=my_db;Trusted_Connection=yes')
Ceci devrait faire l'affaire!
dans le cas où votre SQL n'est pas stocké Proc.
usage de ' xyz != NULL ' dans la requête, donnera la même erreur i.e. "pyodbc.ProgrammingError: aucun résultat. SQL précédent n'était pas une requête."
utiliser 'n'est pas null' à la place.