C# + OracleSQL - 不能在 CommandText 中使用参数

标签 c# sql oracle

我想在 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;

^ 顺便说一句,可能应该有另一种方法来生成 bool 值。可能它会自己将 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 注入(inject)的事情。

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

最佳答案

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

更多信息:

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

关于C# + OracleSQL - 不能在 CommandText 中使用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37393346/

相关文章:

c# - 是否需要异步回调?

c# - 如何将 List<object> 转换为 IEnumerable<T>

mysql - 如何在 sql 中获取最后一个 Row_number() 的示例?

sql - Oracle:一个查询,它计算字符串中所有非字母数字字符的出现次数

c# - 在 C# WPF 中创建索引

c# - WPF 更改组合框的背景颜色

Python postgreSQL sqlalchemy 查询 DATERANGE 列

sql - 返回列的前 n 个字母

oracle - SQL 开发人员错误, "disable modules and continue"

oracle - 修改oracle sql查询输出格式