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).

18
demandé sur Torxed 2011-10-13 16:03:47

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
41
répondu texens 2013-02-20 12:21:21

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.

2
répondu Travis Truax 2017-11-08 21:12:23

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(...)
1
répondu Matt 2016-08-07 23:33:36

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!

0
répondu Torxed 2011-10-26 06:25:24

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.

0
répondu Mitendra 2014-01-16 05:49:53