使用 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>")
我有一个 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>")