如何使用SqlCommand参数为选择查询指定架构名称

本文关键字:查询 SqlCommand 何使用 参数 选择 | 更新日期: 2023-09-27 18:22:02

数据库中Schema的名称是动态的。为什么以下不起作用?

public void ReadVersion(string connString, string schemaName) 
{
    string selectCommand = "SELECT major FROM [@SchemaName].[version]");
    using (SqlConnection sqlConn = new SqlConnection(connString)) 
    {
        using (SqlCommand cmd = new SqlCommand(selectCommand, sqlConn)) 
        {
            sqlConn.Open();
            cmd.Parameters.AddWithValue("@SchemaName", schemaName);
            object result = cmd.ExecuteScalar();
        }
    }
}

执行命令时,参数值不会被替换。这是SqlCommand参数的限制吗?

如何使用SqlCommand参数为选择查询指定架构名称

无法在纯SQL中执行以下操作(因此忽略所有ADO.Net开销):

DECLARE @SchemaName sysname
SET @SchemaName = 'dbo'
SELECT major FROM @SchemaName.[version]

原因很简单。SQL在FROM之后想要的是一个名称。您试图给它一个字符串。SQL Server不会随机开始在字符串内部进行窥视,以查看它们是否类似于其他结构。

对于您的卫生查询,假设您保持了模式名称的理智,只需在信任模式名称之前对其使用一个简单的regex(例如,^[A-Z][A-Z0-9]+$应该足以满足大多数用途)。请确保使用白名单(允许的字符)而不是黑名单。

这是SqlCommand参数的限制吗?

是的,这是一个限制。在ADO.NET中,不能为架构使用参数(例如表名和列名)。您最好的选择是使用字符串串联,很明显,结果是您自己对注入进行过滤。