Почему конкатенация строк создает дополнительные параметры, используя Access и PYODB C? - PullRequest
0 голосов
/ 19 февраля 2020

Example Query

Я создал эту процедуру, которую я вызываю с помощью метода cursor.execute. У меня проблема в том, что PYODB C видит дополнительные параметры, чем я дал. В этом примере запроса " -" и "- " читаются как дополнительные параметры PYODB C. Кто-нибудь знает, почему это так? Это происходит каждый раз, когда я делаю любое объединение строк в Access.

def GetAccessResults(self):

    with pyodbc.connect(SQL.DBPath) as con:
        cursor = con.cursor()

        if self.parameters == None:
            cursor.execute('{{Call {}}}'.format(self.storedProc))
        else:
            callString = self.__CreateStoredProcString()
            cursor.execute(callString, self.parameters)

        returnValue = cursor.fetchall()

    return returnValue

def __CreateStoredProcString(self):

    questionMarks = ('?,' * len(self.parameters))[:-1]

    return '{{Call {} ({})}}'.format(self.storedProc, questionMarks)

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Как выяснил OP, MS Access, являющийся одновременно внешним приложением GUI и базой данных, работает по-разному при запуске SQL. Обычно бэкэнд-режим имеет тенденцию быть ближе к стандартному SQL, а именно:

  • Кавычки : в бэкэнде одинарные кавычки зарезервированы для литералов, а двойные кавычки для идентификаторов в противоположность чтобы быть взаимозаменяемыми внутри MSAccess.exe.
  • Подстановочные знаки : В бэкэнде по умолчанию подстановочные знаки для LIKE используют %, а GUI использует *, если не запущена база данных Access в SQL Синтаксис, совместимый с сервером (ANSI 92) , который использует стандарт %. По этой причине рассмотрим Access 'ALIKE (аналог ANSI) с % для совместимости в обоих режимах доступа. Интересно, что это не относится к хранимым запросам, которые использует OP, но будет, если написание запросов в коде.
  • Параметр : В бэкэнде любой объект без кавычек, не распознанный в запросе, считается именованным параметром и ошибается Тем временем GUI запускает всплывающее окно Ввод параметров (которое новички не знают, что на самом деле является ошибкой во время выполнения), позволяющее затем набирать набранные ответы на лету.
  • GUI Объекты : В то время как в GUI запросы Access могут ссылаться на элементы управления в открытых формах и отчетах, даже на пользовательские функции, определенные в автономных модулях VBA, эти же ссылки будут давать ошибку в бэкэнде, который по сути запускает Access в * Режим 1028 * без головы и распознает только другие таблицы и запросы.
  • Оптимизация : См. Различия Аллена Брауна в оптимизациях , которые могут возникать при создании запросов в GUI по сравнению с бэкэндом, особенно применительно к функциям библиотеки объектов Access.

Кстати, использование LIKE в подзапросе оценивает один скаляр в другой скаляр. Фактически, Access выдаст ошибку, если подзапрос вернет более одной строки, что потенциально может произойти при текущей настройке.

Ошибка 3354: этот подзапрос может вернуть не более одной записи

В других базах данных оценка выполняется в первой строке подзапроса (который без ORDER BY может быть случайной строкой) и не все записи подзапроса. Вместо этого рассмотрите возможность перефакторинга SQL для использования EXISTS предложения:

PARAMETERS prmServiceName Tex(255);
SELECT c.* 
FROM Charts c
WHERE EXISTS
  (SELECT 1 
   FROM Services s
   WHERE s.ServiceName = prmService_Name
     AND c.FileName ALIKE '%-' & s.Service_Abbreviation & '-%');
0 голосов
/ 19 февраля 2020

Попробуйте использовать амперсанды:

Select "*-" & Service_Abbreviation & "-*"

Также, Как и ожидает строку, заключенную в кавычки, и ваш подзапрос не возвращает ее. Итак, возможно:

Select "'*-" & Service_Abbreviation & "-*'"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...