Ошибка привязки собственного параметра функции сервера SQL - PullRequest
7 голосов
/ 29 июня 2010

Я использую следующий программный стек в Ubuntu 10.04 Lucid LTS для подключиться к базе данных:

  1. Python 2.6.5 (пакет Ubuntu)
  2. pyodbc git trunk commit eb545758079a743b2e809e2e219c8848bc6256b2
  3. unixodbc 2.2.11 (пакет ubuntu)
  4. freetds 0.82 (пакет ubuntu)
  5. Windows с Microsoft SQL Server 2000 (8.0)

Я получаю эту ошибку при попытке связать нативные параметры в аргументах к функции SQL SERVER:

Traceback (most recent call last):
 File "/home/nosklo/devel/testes/sqlfunc.py", line 32, in <module>
   cur.execute("SELECT * FROM fn_FuncTest(?)", ('test',))
pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS][SQL
Server]SqlDumpExceptionHandler: Process 54 generated fatal exception
c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this
process.\r\n (0) (SQLPrepare)')

Вот код воспроизведения:

import pyodbc
constring = 'server=myserver;uid=uid;pwd=pwd;database=db;TDS_Version=8.0;driver={FreeTDS}'

con = pyodbc.connect(constring)
print 'VERSION: ', con.getinfo(pyodbc.SQL_DBMS_VER)

cur = con.cursor()
try:
   cur.execute('DROP FUNCTION fn_FuncTest')
   con.commit()
   print "Function dropped"
except pyodbc.Error:
   pass

cur.execute('''
   CREATE FUNCTION fn_FuncTest (@testparam varchar(4))
   RETURNS @retTest TABLE (param varchar(4))
   AS
   BEGIN
       INSERT @retTest
       SELECT @testparam
       RETURN
   END''')
con.commit()

Теперь функция создана. Если я попытаюсь вызвать его, используя прямое значение в запросе (без собственных привязок значений), он будет работать нормально:

cur.execute("SELECT * FROM fn_FuncTest('test')")
assert cur.fetchone()[0] == 'test'

Однако я получаю сообщение об ошибке выше, когда пытаюсь выполнить нативную привязку (используя заполнитель параметра и передавая значение отдельно):

cur.execute("SELECT * FROM fn_FuncTest(?)", ('test',))

Дальнейшее расследование выявило некоторые странные вещи, которые я хотел бы рассказать:

  • Все работает нормально, если я изменю версию TDS на 4.2 (однако, неверный отчет о версии с сервера sql - используя версию TDS 4.2 я получаю '95.08.0255' вместо реальной версии '08.00.0760').
  • Все отлично работает для двух других типов функций -> функции, которые возвращают значение и функции, которые просто SELECT запрос (как вид) оба работают нормально. Вы даже можете определить новую функцию который возвращает результат запроса другой (неработающей) функции, и Таким образом, все будет работать, , даже если родные привязки на Параметры . Например: CREATE FUNCTION fn_tempFunc(@testparam varchar(4)) RETURNS TABLE AS RETURN (SELECT * FROM fn_FuncTest(@testparam))
  • После этой ошибки соединение становится очень нестабильным, восстановление невозможно.
  • Ошибка возникает при попытке связать данные любого типа.

Как я могу продолжить это? Я хотел бы сделать нативные привязки к параметрам функции.

1 Ответ

0 голосов
/ 10 июля 2010

В конечном счете, это, вероятно, не тот ответ, который вы ищете, но когда мне пришлось подключиться к MSSQL из Perl два или три года назад, изначально был задействован ODBC + FreeTDS, и я ничего не получил с ним (хотя я не помню конкретных ошибок, я пытался выполнить связывание, и это казалось источником некоторых проблем).

В проекте Perl я, в конечном счете, использовал драйвер, предназначенный для Sybase (который MSSQL отключил), так что вы можете захотеть разобраться в этом.

В вики Python есть страница на Sybase и другая на SQL Server, которую вы, вероятно, захотите просмотреть для альтернатив:

http://wiki.python.org/moin/Sybase

http://wiki.python.org/moin/SQL%20Server

...