【问题标题】:C# + OracleSQL - can't use parameters in CommandTextC# + OracleSQL - 不能在 CommandText 中使用参数
【发布时间】:2016-05-23 14:10:43
【问题描述】:

我想在 C# 中创建简单的登录 + 注册表单,基于 OracleSQL。我正在使用 Oracle 的 ManagedDataAccess 客户端(来自 NuGet)。

我尝试这样使用它:

OracleCommand query = db.CreateCommand();
query.CommandText = string.Format("insert into @tablename values(null, '@login', '@pwd', 0, null)");
query.Parameters.Add("@tablename", ConfigurationManager.AppSettings.Get("usersTableName"));
query.Parameters.Add(name: "@login", val: login);
query.Parameters.Add(name: "@pwd", val: HashPassword(pwd));
bool isCreated = (query.ExecuteReader().RecordsAffected > 0 ? true : false);
query.Dispose();
return isCreated;

^ 顺便说一句,可能应该有另一种方法来制作该布尔值。可能它会自行将 int 转换为 bool。

那里的结构很简单:

"USERS" 
(
"ID" NUMBER(10,0), 
"USERNAME" VARCHAR2(16 BYTE), 
"PASSWORD" VARCHAR2(64 BYTE), 
"IS_LOGGED" NUMBER(1,0), 
"IP" VARCHAR2(15 BYTE)
)

该代码失败。尝试使用“@”、冒号等。如果我让它工作,它会添加带有“@login”用户名的记录。从字面上看,我在参数名称中所写的内容。此外,它说 ORA-00903 错误“无效的表名”(它可能将名称发送为“@tablename”)...

代码是这样工作的:

string q = string.Format("insert into {0} values(null, '{1}', '{2}', 0, null)", 
ConfigurationManager.AppSettings.Get("usersTableName"), login, HashPassword(pwd));

当我将此字符串用作查询的 CommandText 时,它运行良好。我不喜欢保持这种方式,尤其是因为 SQL 注入的事情。

我是 C# 的新手,所以我可能在这么短的代码中犯了很多错误。

【问题讨论】:

  • 去掉'@login'和'@pwd'周围的引号
  • @BugFinder 感谢您的快速回答!不幸的是,它没有按应有的方式工作。现在我有 ORA-00936 错误 - 没有表达式。我保留引号,因为@login 和@pwd 是字符串。
  • 是的,但参数应该为您解决!虽然msdn.microsoft.com/en-us/library/… 建议您应该使用 : 而不是 @ ...也许这就是答案
  • 我也尝试过使用冒号(这是我的第一个版本) - 仍然没有用
  • Oracle 的ManagedDataAccess Client 支持表名参数吗?真的吗?

标签: c# sql oracle


【解决方案1】:

表名和列名不能作为参数。因为它会阻止 Oracle SQL 解析器解析查询并创建执行计划。 您在查询文本中使用了“@tablename”参数,例如,您必须删除此参数并将其替换为“usersTableName”。 使用 @ 作为参数说明符是在 .Net 环境(包括 C#)中为包括 Oracle 在内的任何 DBMS 定义绑定参数的正确方法。虽然使用 ':' 对于 Oracle 也是正确的。

更多信息:

使用为提高性能和避免 SQL 注入而推荐的绑定参数。提高性能是 Oracle 缓存执行计划的结果,然后参数不能改变 SQL 语句的结构。

【讨论】:

    【解决方案2】:

    您不能在 Oracle SQL 中绑定表名。您可以改为这样做(并记住在构建这样的 SQL 时要注意 SQL 注入)

                OracleCommand query = db.CreateCommand();
            query.CommandText = string.Format("insert into " + 
                ConfigurationManager.AppSettings.Get("usersTableName") +
                " values(null, :login, :pwd, 0, null)");
            query.Parameters.Add(":login", login);
            query.Parameters.Add(":pwd", HashPassword(pwd));
            bool isCreated = (query.ExecuteReader().RecordsAffected > 0 ? true : false);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多