如何在不使用 %s 的情况下安全、动态地在查询中设置列名?

Posted

技术标签:

【中文标题】如何在不使用 %s 的情况下安全、动态地在查询中设置列名?【英文标题】:How can I safely and dynamically set column names in a query without using %s? 【发布时间】:2021-11-01 15:26:18 【问题描述】:

我正在为同事制作一个脚本,以便能够从 SQL Server 数据库生成报告。我正在使用 pymssql 来管理与数据库的连接。

我的问题是我希望使用脚本的人能够指定他们想要返回的列,以及他们需要的日期范围。

我正在使用这个 sn-p 代码,但列名不起作用(据我了解,它们被转义,这是问题的一部分)VS 将它们输入。

if len(columns) == 1:
    query = "SELECT %s FROM dbo.tblPayments WHERE %s < dbo.tblPayments.fldPayDate AND dbo.tblPayments.fldPayDate > %s;"
else:
    query = "SELECT " + ("%s, " * (len(columns) - 1)) + "%s FROM dbo.tblPayments WHERE %s <= dbo.tblPayments.fldPayDate AND dbo.tblPayments.fldPayDate >= %s;"

我看到有人说要使用.format() 的字符串连接,但如果可以避免它们,我不想插入安全风险。有什么我想念的吗?我可以做些什么来确保它的安全?

谢谢

【问题讨论】:

【参考方案1】:

您可以使用sys.columns 视图查找某个表的所有列。首先获取列表并使用此结果验证应用程序中的用户输入。如果找到该列,您可以使用它来构建query 字符串。

SELECT c.name
FROM sys.columns c
WHERE OBJECT_SCHEMA_NAME ( c.object_id) ='dbo'
AND OBJECT_NAME(c.object_id) = 'tblPayments'

【讨论】:

感谢您提供这个优雅的解决方案。它适用于这个脚本。

以上是关于如何在不使用 %s 的情况下安全、动态地在查询中设置列名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 join 或 cte 的情况下在同一查询中使用动态生成的列

如何在不使用 AudioQueueRef 的情况下在 AudioQueue 中设置音量?

如何在不插入值的情况下在sql中创建动态行?

如何在不提交页面的情况下刷新 PL/SQL 动态内容区域

如何在不使用数据库的情况下重新实例化动态 ASP.NET 用户控件?

在不更改选定选项卡的情况下动态更新 TabLayout