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

Gar*_*wen 3 c# t-sql sql-server ado.net

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Dam*_*ver 5

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

DECLARE @SchemaName sysname
SET @SchemaName = 'dbo'
SELECT major FROM @SchemaName.[version]
Run Code Online (Sandbox Code Playgroud)

原因很简单。SQL 想要的FROM是一个名称。你想要给它的是一个string。SQL Server不会随机开始查看字符串内部以查看它们是否类似于其他构造。

对于您的卫生查询,假设您保持模式名称正常,只需在信任模式名称之前使用简单的正则表达式即可(例如,^[A-Z][A-Z0-9]+$对于大多数用途来说应该足够了)。确保使用白名单(允许的字符)而不是黑名单。