2016-12-23 7 views
3

Я пытаюсь вызвать хранимую процедуру в Python, но он продолжает давать мне следующую ошибку. Процедура написана в SQL Server 2008, и я использую PyODBC для вызова метода и передачи ему параметров.Ошибка «Предыдущий SQL не был запросом» в Python?

import pyodbc 
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER='+serveripaddr+';DATABASE='+database+';UID='+userid+';PWD='+password+'') 
cursor = cnxn.cursor() 
cursor.execute("{call p_GetTransactionsStats('KENYA', '41')}") 
rows = cursor.fetchall() 

Последние результаты в линии за исключением следующего:

ProgrammingError: No results. Previous SQL was not a query. 

Что может быть проблема?

+0

Какая ошибка возникает, поскольку у вас есть два комментария? – Parfait

ответ

1

Вы можете добавить SET NOCOUNT ON вам SP и попробовать , если вы не можете изменить SP, первым выполнить эту инструкцию Xand затем вызовите SP

+0

: - Я попробовал, и он отлично работал на сервере, но не работает с python. –

+0

@jessica - ошибка, безусловно, выглядит как отсутствующая 'SET NOCOUNT ON;' * в самой хранимой процедуре *. Вы действительно подтвердили, что 'SET NOCOUNT ON;' является первым исполняемым оператором в хранимой процедуре? –

5

Вот что происходит. Хранимая процедура содержит несколько шагов. Когда он выполняется из студии SQL Server Management, легко увидеть, как каждый шаг приводит к отдельному сообщению, например "(3 row(s) affected)", и только последний шаг дает ответ.

Очевидно, что при вызове через pyodbc курсора, каждый из этих отдельных шагов создает отдельный resultset, где все результирующие, но самые последние один, не содержат никаких данных, которые могут быть считаны с помощью fetchall().

Таким образом, один вариант, чтобы решить эту проблему, чтобы перебирать эти ResultSets с помощью nextset(), пока не найдете тот, который действительно производит результат, например:

while cursor.nextset(): # NB: This always skips the first resultset 
    try: 
     results = cursor.fetchall() 
     break 
    except pyodbc.ProgrammingError: 
     continue 

приятнее вариант, как уже упоминалось в другой ответ , использовать директиву SET NOCOUNT ON;, которая, как представляется, предотвращает все промежуточные, пустые (# rows affected). Директива может быть просто добавлена ​​к вызову proc, например:

cursor.execute("set nocount on; exec MyStoredProc ?", some_parameter) 
results = cursor.fetchall() 

 Смежные вопросы

  • Нет связанных вопросов^_^