2010-12-01 9 views
0

essaie d'exécuter le code ci-dessous en utilisant python 2.5.2. Le script établit la connexion et crée la table, mais son échec avec l'erreur ci-dessous.Erreur de rétrolien python - en utilisant pymssql

Le script

import pymssql 
conn = pymssql.connect(host='10.103.8.75', user='mo', password='the_password', database='SR_WF_MODEL') 
cur = conn.cursor() 
cur.execute('CREATE TABLE persons(id INT, name VARCHAR(100))') 
cur.executemany("INSERT INTO persons VALUES(%d, %s)", \ 
    [ (1, 'John Doe'), (2, 'Jane Doe') ]) 
conn.commit() 

cur.execute("SELECT * FROM persons WHERE salesrep='%s'", 'John Doe') 
row = cur.fetchone() 
while row: 
    print "ID=%d, Name=%s" % (row[0], row[1]) 
    row = cur.fetchone() 

cur.execute("SELECT * FROM persons WHERE salesrep LIKE 'J%'") 

conn.close() 

L'erreur

Traceback (most recent call last): 
    File "connect_to_mssql.py", line 9, in <module> 
    cur.execute("SELECT * FROM persons WHERE salesrep='%s'", 'John Doe') 
    File "/var/lib/python-support/python2.5/pymssql.py", line 126, in execute 
    self.executemany(operation, (params,)) 
    File "/var/lib/python-support/python2.5/pymssql.py", line 152, in executemany 
    raise DatabaseError, "internal error: %s" % self.__source.errmsg() 
pymssql.DatabaseError: internal error: None 

des suggestions? plus, comment lisez-vous l'erreur de traceback, n'importe qui peut m'aider à comprendre le message d'erreur? comment le lis-tu? de bas en haut?

+0

Cette traceback est une mauvaise blague. Si l'erreur est "Aucun", alors pourquoi se plaindre? Et oui, les retraçages sont lus de bas en haut. Chaque ligne est la ligne qui a appelé la ligne ci-dessous. – aaronasterling

+2

Il n'y a pas de colonne 'salesrep', seulement' name' –

Répondre

1

Je pense que vous assumez le comportement régulier d'interpolation de chaîne de python, à savoir:

>>> a = "we should never do '%s' when working with dbs" 
>>> a % 'this' 
"we should never do 'this' when working with dbs" 

L'opérateur % dans la méthode exécuter ressemble à l'opérateur normal de mise en forme de chaîne, mais qui est plus d'une commodité ou mnémotechnique; votre code doit lire:

cur.execute("SELECT * FROM persons WHERE salesrep=%s", 'John Doe')

sans les guillemets, et cela fonctionnera avec des noms comme O'Reilly, et aider à prévenir l'injection SQL par la conception de l'adaptateur de base de données. C'est vraiment ce que l'adaptateur de base de données est là pour - convertir les objets python en SQL; il saura citer une chaîne et échapper correctement la ponctuation, etc. Il fonctionnerait si vous avez:

>>> THING_ONE_SHOULD_NEVER_DO = "select * from table where cond = '%s'" 
>>> query = THING_ONE_SHOULD_NEVER_DO % 'john doe' 
>>> query 
"select * from table where cond = 'john doe'" 
>>> cur.execute(query) 

mais cela est une mauvaise pratique.