Pracuję z Python 3.3, PYPYODBC 1.2.1, a plik QuickBooks Enterprise 12 jest dostępem nad FlexQuarters Qowbc w wersji 14. Jestem nowy w programowaniu i pytonie, więc wciąż się ucząc :) Mogę uruchomić zapytanie za pomocą przykładów PYPYODBC W porządku i produkuje oczekiwane wyniki.

Zwróć uwagę na dyskowany adres e-mail w wykonaniu. Działa to zgodnie z oczekiwaniami:

def get_customer_id(search_col,search_str):
    '''(str,str) --> str

    >>>get_customer_id(email, foo@foo.com)
    80000001-1385782702
    '''
    cur.execute("SELECT listid FROM CUSTOMER WHERE email='foo@foo.com'")
    for row in cur.fetchall():
        for field in row: 
            return field

Jeśli spróbuję zrobić to samo za pomocą parametrów, które czytam z dokumentacji PYPYODBC, rzucam błąd. Mam problemy z cytatami i myślę, że markery parametrów.

def get_customer_id(search_col,search_str):
    '''(str,str) --> str

    >>>get_customer_id(email, foo@foo.com)
    80000001-1385782702
    '''
    cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",(search_str,))
    for row in cur.fetchall():
        for field in row: 
            return field

Próbując być bardziej pythonistycznym? Naprawdę chcę ponownie wykorzystać funkcję do wyszukiwania różnych kolumn. Coś jak:

cur.execute("SELECT listid FROM CUSTOMER WHERE search_str=search_col")

Spojrzałem na kilka innych wątków, a większość z nich wydaje się po prostu zajmować się parametrem, a nie kolumną do wyszukiwania. Czy ktoś może mi pomóc

PS Zapomniał dołączyć Traceback:

Traceback (most recent call last):
  File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 32, in <module>
    print(get_customer_id('email','foo@foo.com'))
  File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 27, in get_customer_id
    cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",[search_str,])
  File "C:\Python\lib\site-packages\pypyodbc.py", line 1457, in execute
    self._BindParams(param_types)
  File "C:\Python\lib\site-packages\pypyodbc.py", line 1420, in _BindParams
    check_success(self, ret)
  File "C:\Python\lib\site-packages\pypyodbc.py", line 982, in check_success
    ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
  File "C:\Python\lib\site-packages\pypyodbc.py", line 960, in ctrl_err
    raise Error(state,err_text)
pypyodbc.Error: ('HY004', '[HY004] [Microsoft][ODBC Driver Manager] SQL data type out of range')
[Finished in 1.7s]
2
MLindsay 2 grudzień 2013, 00:38

3 odpowiedzi

Najlepsza odpowiedź

Myślę, że użycie

cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])

Nie można zaakceptować przez silnik bazy danych, a nie pypiodbc lub innego interfejsu ODBC. Jest to silnik bazy danych odmówić przyjęcia zapytania do użycia parametru na nazwach kolumn.

Prawdopodobnie musiałbyś spróbować tego, aby ponownie wykorzystać funkcję:

# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE %s=?""" %(column) 

# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))
3
pypyodbc 2 grudzień 2013, 07:36

Python 3 ma również metodę str.format (), która zrobi wymianę ciągów na {index} w swoim ciągu. Jest to przydatne, jeśli masz wiele wartości do wstrzykiwania w struny, takie jak:

Mystr = "Lubię {0} i {1}, ale nie lubię {2}.". Format ("jabłka", "banany", "szpinak")
Mystir
. "Lubię jabłka i banany, ale nie lubię szpinaku".

# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE {0}=?""".format(column) 

# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))

Warto zauważyć, że ta metoda zastępowania wartości w zapytaniu ciągu może podlegać wtrysku SQL. Bezpieczniejszym sposobem na to byłoby z parametryzowanymi procesowymi procesami.

1
Emilia 1 listopad 2017, 16:22

Dostałem do tej pory 1/2 odpowiedzi. Działa to dla jednego parametru, jeśli sformatuję ciąg przed wywołaniem funkcji;

print(get_custid_email(b'foo@foo.org'))

cur.execute("""SELECT listid FROM CUSTOMER WHERE email=?""",[email])

Nadal nie mogę go zrobić, aby zrobić to samo z nazwą kolumną.

print(get_custid_email(b'email',b'foo@foo.org'))

cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])

Który rzuca inny błąd:

Traceback (most recent call last):
  File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 34, in <module>
    print(get_custid_email(b'wendy.lindsay@gmail.com'))
  File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 29, in get_custid_email
    cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",['email',email])
pyodbc.ProgrammingError: ('42S00', '[42S00] [QODBC] Data type of parameter cannot be determined (11023) (SQLPrepare)')
0
MLindsay 2 grudzień 2013, 05:45