如何安全地创建一个查询,该查询将列出给定表名的列名,以及可能指向 SQL Server 或 MySQL 的连接字符串?
Posted
技术标签:
【中文标题】如何安全地创建一个查询,该查询将列出给定表名的列名,以及可能指向 SQL Server 或 MySQL 的连接字符串?【英文标题】:How can I safely create a query that will list column names given a table name, and a connection string which may point to SQL Server or MySQL? 【发布时间】:2019-10-20 20:35:57 【问题描述】:目前我有以下方法适用于我的特定两个数据库,但我不确定这是否是实现列出列名的目标的正确方法,或者有点hacky。
让我担心的一个部分是 SQL Server 似乎使用 TABLE_CATALOG
作为数据库名称,而 mysql 使用 TABLE_SCHEMA
。我不确定我是否可以在任何情况下都依赖它。
private string GetTableColumnsQuery(ConnectionStringSettings conString, string tableName)
string query;
if (conString.Name == "mysql")
var con = new MySqlConnectionStringBuilder(conString.ConnectionString);
query = $"select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='tableName' and TABLE_SCHEMA='con.Database'";
else
var con = new SqlConnectionStringBuilder(conString.ConnectionString);
query = $"select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='tableName' and TABLE_CATALOG='con.Database'";
return query;
这是否适用于所有 SQL Server 和 MySQL 数据库,我是否应该以某种方式对其进行更改以避免我遗漏的错误?
最后,如果代码绝不是面向用户的,是否仍然鼓励使用准备好的语句?
谢谢。
【问题讨论】:
【参考方案1】:MySQL 和 SQL Server 长期以来都支持INFORMATION_SCHEMA
视图。所以你的代码应该在任一数据库中工作。您只选择列名,因此表中的其他差异不会影响您的代码。 “模式”的解释略有不同,但代码本身应该可以工作。
是的,您应该参数化您正在编写的所有查询。首先,这是一个好习惯——您不希望为内部目的编写的代码被“扩展”,从而引入 SQL 注入风险。
其他问题是查询计划的重用和避免语法错误。修改查询字符串并不是传递参数的最佳方式。
【讨论】:
给我两分钱:除了消除 SQL 注入风险(这非常重要)之外,它的工作速度更快,正如你所拥有的(至少在 SQL Server 方面,我并不真正喜欢 mySQL)编译执行计划。以上是关于如何安全地创建一个查询,该查询将列出给定表名的列名,以及可能指向 SQL Server 或 MySQL 的连接字符串?的主要内容,如果未能解决你的问题,请参考以下文章
oracle中已经知道一个具体值,如何根据该值查询出含有该值的表名和列名?