使用 Pyodbc 包从 sql 数据库中获取数据

Fetch data from sql database using Pyodbc package

我有一个 streamlit 应用程序可以从我使用 pyodbc 的 sql 服务器数据库中检索数据。

我有一个 select 查询,我尝试在 sql 查询中使用通配符根据用户输入 select 数据。

问题是,当用户搜索 ID 旁边的任何字段时,它不会 return 任何内容。

数据库:

CREATE TABLE [dbo].[t1](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [first] [nvarchar](50) NULL,
    [last] [nchar](50) NULL,
    [Rating] [int] NULL,
 CONSTRAINT [PK_t1] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Python代码:

import pandas as pd 
import streamlit as st

advanced_search_term_list = []

if len(advanced_search_term_list)>0:

   sql="select * from testDB.dbo.t1 where (ID = ? OR ID is null) and (first LIKE  ? OR first is null) and (last LIKE ? or last is null) and (Rating = ? or Rating is null) "   

   param0=advanced_search_term_list[0]

   param1=f'%{advanced_search_term_list[1]}%'

   param2=f'%{advanced_search_term_list[2]}%'

   param3=advanced_search_term_list[3]

   rows = cursor.execute(sql,param0,param1,param2,param3).fetchall()

查询的只是param0

的return数据

我的代码哪里出错了?

如果我理解正确,你需要解决这些问题:

  • 使用参数,而不是 WHERE 条件的 IS NULL 部分中的列名(正如@Charlieface 在评论中解释的那样)
  • 使用 LIKE CONCAT('%', ?, '%') 正确处理 Python 的 None 值,当您使用 cursor.execute().

以下工作示例可以解决您的问题:

Table:

CREATE TABLE [dbo].[t1] (
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [first] [nvarchar](50) NULL,
    [last] [nchar](50) NULL,
    [Rating] [int] NULL
) ON [PRIMARY]
INSERT INTO [dbo].[t1] ([first], [last], [Rating])
VALUES 
    ('AB', 'CD', 100),
    ('EF', 'GH', 101),
    ('IJ', 'KL', 100)

Python:

sql = (
    r"select ID, first, last, Rating "
    r"from dbo.t1 "
    r"where "
        r"(ID = ? OR ? IS NULL) AND "
        r"(first LIKE CONCAT('%', ?, '%') OR ? IS NULL) AND "
        r"(last LIKE CONCAT('%', ?, '%') OR ? IS NULL) AND "
        r"(Rating = ? OR ? IS NULL)"   
)
# Only for test. The values of the advanced_search_term_list
# come from the user input.     
advanced_search_term_list = [1, 'AB', None, 100]
param0 = advanced_search_term_list[0]
param1 = advanced_search_term_list[1]
param2 = advanced_search_term_list[2]
param3 = advanced_search_term_list[3]

for row in cursor.execute(sql, [param0, param0, param1, param1, param2, param2, param3, param3]) :
    print(row.ID)
    print(row.first)
    print(row.last)
    print(row.Rating)
    print("<br>")