如何安全地创建一个查询,该查询将列出给定表名的列名,以及可能指向 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 的连接字符串?的主要内容,如果未能解决你的问题,请参考以下文章

从函数中获取给定表名的列名

用于检索给定模式的所有表名的 DB2 查询

oracle中已经知道一个具体值,如何根据该值查询出含有该值的表名和列名?

如何最好地修改带有表前缀的 sql 查询

从给定数据库中选择所有表时,如何将 [dbo] 前缀附加到表名?

SQL VBA:选择具有特定表名和字段名的所有表