如何在Python中正确执行带参数的MSSQL存储过程

Krz*_*zyk 3 python sql-server sql-injection sqlalchemy python-3.x

目前我正在以这种方式执行存储过程:

engine = sqlalchemy.create_engine(self.getSql_conn_url())
query = "exec sp_getVariablesList @City = '{0}', @Station='{1}'".format(City, Station)
self.Variables = pd.read_sql_query(query, engine)
Run Code Online (Sandbox Code Playgroud)

但是在sqlalchemy 的 How set ARITHABORT ON 中,我们正确地注意到这使得 SQL 注入变得开放。我尝试了不同的方法但没有成功。那么应该如何向MSSQL存储过程传递参数来消除SQL注入的风险呢?这可以通过 sqlalchemy 或任何其他方式来实现。

Gor*_*son 7

使用“命名”参数样式编写 SQL 命令文本,将其包装在 SQLAlchemytext()对象中,并将参数值作为字典传递:

import pandas as pd
import sqlalchemy as sa

connection_uri = "mssql+pyodbc://@mssqlLocal64"
engine = sa.create_engine(connection_uri)

# SQL command text using "named" paramstyle
sql = """
SET NOCOUNT ON;
SET ARITHABORT ON;
EXEC dbo.breakfast @name = :name_param, @food = :food_param;
"""
# parameter values
param_values = {"name_param": "Gord", "food_param": "bacon"}
# execute query wrapped in SQLAlchemy text() object
df = pd.read_sql_query(sa.text(sql), engine, params=param_values)

print(df)
"""
                           column1
0  Gord likes bacon for breakfast.
"""
Run Code Online (Sandbox Code Playgroud)