为啥我的 sql 命令不接受表名的带引号标识符?

Posted

技术标签:

【中文标题】为啥我的 sql 命令不接受表名的带引号标识符?【英文标题】:Why isn't my sql command accepting a quoted identifier for a table name?为什么我的 sql 命令不接受表名的带引号标识符? 【发布时间】:2016-04-26 05:09:25 【问题描述】:

我想做我的 sql 查询防弹,发现this关于清理表/列名的问题。

我听从了建议,但不知何故,它没有按预期工作。

我的表名是foo.Bar,所以我将它传递给CommandBuilderQuoteIdentifier 方法,它给了我[foo.Bar]

当我打电话给(string)cmd.ExecuteScalar(); 时,它抱怨这个表不存在。所以我最初尝试将表名定义为[foo].[Bar]。在这种情况下,QuoteIdentifier 创建了 [[foo]].[Bar]]],这也不起作用。

唯一有效的是我只指定[foo].[Bar] 而不使用QuoteIdentifier 方法。

此时我想知道是否可以使用它来保护我的查询?它没有多大用处,并且调整像another answer 这样的引用查询似乎也不正确。

我能做些什么来保护查询并使其工作并接受名称[foo].[Bar] 而不会破坏它?

这就是我创建查询的方式:

cmd.CommandText = string.Format(
    "SELECT 0 FROM 1 WHERE 2 = '3'4",
    ...,
    sanitizedTableName, // only [foo].[Bar] works -- [[foo]].[Bar]]] and [foo.Bar] fail
    ...,
    ...,
    ...);

【问题讨论】:

你试过SqlParameter吗? msdn.microsoft.com/en-us/library/… @buffjape 我打算稍后将它用于3 值。我也可以用它来插入表名吗?我从来没有尝试插入任何其他东西。我想这是我见过的唯一用法......我会尝试一下,我们马上就会看到;-) 如果您使用参数化查询,则不需要引号。只需添加一个参数并指定数据库中列的类型即可。 @Gnqz 这不是我遇到问题的参数(稍后我将使用参数)。目前它不喜欢表名,但我会尝试使用它们作为它的名称,就像 buffjape 建议的那样。我不知道我也可以将它们用于表名。 问题是,您的表名不是 foo.bar。您的表的名称是 bar 并且它在 foo 模式中。尝试使用只希望处理表名的函数对其进行清理将会失败,因为它们会假设 . 是名称的一部分而不是分隔符。 【参考方案1】:

问题是表的名称是bar,而不是foo.bar。您正在使用多部分标识符 - foo 是架构,bar 是表名。

要获得正确的引用,您需要分别引用每个标识符:

QuoteIdentifier(schemaName) + "." + QuoteIdentifier(tableName)

这样做的原因应该很明显 - 带引号的标识符使用 . 作为名称的一部分是完全有效的。这就是首先引用的全部意义所在。

【讨论】:

以上是关于为啥我的 sql 命令不接受表名的带引号标识符?的主要内容,如果未能解决你的问题,请参考以下文章

oracle sql用的mysql软件,查关联的表名的时候会有表名和后面的括号,如图

如何在 Oracle 中为用户 + 表名组合使用带引号的标识符?

将数据导入mysql中,总是提示“DROP TABLE IF EXISTS XXX(我的表名)”出错,求大神指导!!

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

如何安全地创建一个查询,该查询将列出给定表名的列名,以及可能指向 SQL Server 或 MySQL 的连接字符串?

在 SQL Server 存储过程中查找表名的列名作为保留关键字