我遇到了一个问题,我不知道我应该如何传入一个Oracle参数,其中C#类型是string
且Oracle类型是{ {1}}。
目前我正在传递此Varchar2
string
,认为Oracle会在CMS','ABC
{{}}}中添加''
,使其成为string
看起来像varchar2
。
这适用于'CMS','ABC'
这样的单string
,但是当值较长时,就像CMS
命令中的某些内容一样,参数不会被正确传递。
这也是我所指的代码。
IN (list)
如果传入的string sql = 'SELECT name FROM Pers p WHERE p.FirstName IN (:names)';
的值为:names
而没有任何引号,则以下内容有效。
CML
当传入的OracleParameter param = new OracleParameter(":names", OracleDbType.Varchar2, "CML", ParameterDirection.Input);
的值为:names
且内部带引号时,以下内容无效。
CML','ABC
为什么?
当参数传递到sql语句时,Oracle是否在参数周围添加单引号?为什么不在第二种情况下添加引号呢?
答案 0 :(得分:2)
ODP.NET参数不适用于多个逗号分隔值。每个参数都被视为单个值,无论它包含什么类型的引号。
Oracle在传递给查询时不会在参数值周围添加引号。引号只是在查询中编写VARCHAR值的一种方法,但是在使用参数时,Oracle不会“用其值替换您的参数然后执行查询”,因为这将允许SQL注入。
如果是这种情况,请假设您的参数值为:"CML', 'ABC');DROP DATABASE Test;--"
。然后,Oracle将执行SELECT name FROM Pers p WHERE p.FirstName IN ('CML', 'ABC');DROP DATABASE Test;--'
!
有关如何解决问题的建议,请参阅此问题:Oracle Parameters with IN statement?
答案 1 :(得分:2)
从您的评论/答案中,我能够提出这个解决方案。我希望它可以帮助其他人。
要绕过不使用多个逗号分隔值的ODT.NET参数,可以将每个值划分为自己的参数。如下所示。
string allParams = "CML, ABC, DEF";
string formattedParams = allParams.Replace(" ", string.Empty); // Or a custom format
string [] splitParams = formattedParams.Split(',');
List<OracleParamter> parameters = new List<OracleParameter>();
string sql = @"SELECT * FROM FooTable WHERE FooValue IN (";
for(int i = 0; i < splitParams.Length; i++)
{
sql += @":FooParam" + i + ",";
parameters.Add(new OracleParameter(":FooParam" + i, OracleDbType.Varchar2, splitParams[i], ParameterDirection.Input));
{
sql = sql.Substring(0, (sql.Length - 1));
sql += ')';
字符串sql
现在将其值为SELECT * FROM FooTable WHERE FooValue IN (:FooParam0,:fooParam1, etc...)
这将解决问题。
另一种方法是为每个参数添加一堆OR
子句。上面的例子更好,因为你没有写一堆OR
子句。