将参数传递给 ExecuteSql()

Pass parameters to ExecuteSql()

我正在尝试将 table 名称作为参数传递给 ExecuteSql() 方法。

这是我试过的:

        var viewName = "search_view";

        using (var db = dbFactory.Open())
        {
            db.ExecuteSql("REFRESH MATERIALIZED VIEW @viewName;", new { viewName });
        }

它不起作用,它创建异常并显示消息:

Npgsql.PostgresException

42601: syntax error at or near ""

我启用了日志记录以尝试查看生成了什么 SQL,但我认为由于异常,查询未被记录。

当查询全是文本时,查询运行良好,我将 table 名称作为参数传递时做错了什么?

您只能使用数据库参数替代 参数 ,即您不能像您一样将它们用作 SQL 模板生成的自由文本替代正在尝试做。

您需要在 SQL 中使用 viewName,例如:

db.ExecuteSql($"REFRESH MATERIALIZED VIEW {viewName};");

尽管如果 viewName 是由用户提供的,您将需要保护它免受可能的 SQL 注入。我的建议是检查允许的 viewNames 的白名单,例如:

if (!AllowedViewNames.Contains(viewName))
    throw new Exception("Invalid View");

在 OrmLite 中,您可以使用 GetQuotedValue() API 转义字符串,例如:

var quotedViewName = db.GetDialectProvider().GetQuotedValue(viewName);

要检测符号的无效名称(如视图名称),您可以使用 RegEx 仅允许有效字符,例如:

if (!new Regex(@"[^A-Za-z0-9_]").IsMatch(viewName))
    throw new Exception("Invalid View");

虽然 OrmLite 的 SqlVerifyFragment() 扩展方法允许您检测潜在的非法 SQL 注入,如果您想接受 SQL 片段,例如:

db.ExecuteSql($"SELECT * FROM User WHERE {userSql.SqlVerifyFragment()}");

如果 OrmLite 检测到潜在的非法 SQL 违规行为,OrmLite 将抛出 ArgumentException