2015-04-22 102 views
2

我是编程和编写作业的新手。我试图通过将用户的搜索词与选定列中的任何匹配值进行比较来搜索数据库。如果用户搜索“Smith”并单击我的GUI中的“Smith”单选按钮,则应显示包含“Smith”作为其作者的所有记录。我可以打印数据库中的所有记录,但不能打印与我的搜索相关的记录。Python:使用SQL搜索数据库

db = None 
colNum = None 

def search_db(self): 
    global db 
    global colNum 

    self.searchTerm = self.searchvalue.get() 
    dbname = 'books.db' 
    if os.path.exists(dbname): 
     db = sqlite3.connect(dbname) 
     cursor = db.cursor() 
     sql = 'SELECT * FROM BOOKS' 
     cursor.execute(sql) 
     rows = cursor.fetchall() 
     for record in rows: 
      sql_search = 'SELECT * FROM BOOKS WHERE' + ' ' + record[colNum] + ' ' + 'LIKE "%' + ' ' + self.searchTerm + '%"' 
      cursor.execute(sql_search) 
      searched_rows = cursor.fetchall() 
     print(searched_rows) 

我收到的错误是“sqlite3.OperationalError:没有这样的栏目:”

+4

这不是你的问题,但[你不应该用这种方式在它们的动态数据中构建SQL语句](https://xkcd.com/327/)。 – abarnert

回答

1

没有在你的问题足够的信息可以肯定的,但是这肯定是腥:

sql_search = 'SELECT * FROM BOOKS WHERE' + ' ' + record[colNum] + ' ' + 'LIKE "%' + ' ' + self.searchTerm + '%"' 

record[colNum]表示列的值,而不是列的名称。例如,如果您想要的列是Title,那么您会将每本书的每个标题看作是列名。

所以,你最终运行的查询是这样的:

SELECT * FROM BOOKS WHERE The Meaning of Life: The Script like %Spam% 

即使这是有效的SQL(引用正确),The Meaning of Life: The Script可能不是在BOOKS表中的列。


同时,SELECT *返回以任意顺序列,因此使用colNum是不是真的保证做任何有用的。但是,如果你真的想这样做你想要做什么,我认为这是这样的:

sql = 'SELECT * FROM BOOKS' 
cursor.execute(sql) 
colName = cursor.description[colNum][0] 
sql_search = 'SELECT * FROM BOOKS WHERE ' + colName + ' LIKE "%' + ' ' + self.searchTerm + '%"' 

但是,你真的不应该想这样做...

-1

它看起来对我来说,你只是没有正确地形成SQL。记住,无论你在LIKE子句后面加什么都需要引用。你的SQL需要看起来像

SELECT * FROM BOOKS WHERE Title like '%Spam%' 

所以你需要另一套单引号中就有所以这就是为什么我会用双引号包围你的Python字符串:您需要得到列

sql_search = "SELECT * FROM BOOKS WHERE " + record[colNum] + " LIKE '%" + self.searchTerm + "%'" 
+0

不正确引用通常是这些查询错误的原因,但在这种情况下,这不是原因。记录[colNum]返回一个数据字段而不是列名。 – philshem

+0

我没有引用记录[colNum]我将引号添加到LIKE子句中。原始代码围绕Python字符串使用单引号,并且围绕SQL字符串使用双引号。 SQL从不使用双引号来包围字符串常量,这就是为什么我将其颠倒过来的原因。当你在SQL中双引号时,它将它作为命名对象的标识符而不是字符串常量。 –

+0

记录[colNum]是数据,而不是标题。 – philshem

0

名称来自表格的字段,或来自其他地方。您的查询使用记录[colNum],但记录包含数据行。相反,以获得字段名,使用这样的:

fields = [] 
for field in cursor.description: 
    fields.append(field[0]) 

当您使用rows = cursor.fetchall(),你只得到数据(而不是列标题)。