将Oracle参数传递给SQL字符串

时间:2018-06-01 14:33:36

标签: c# sql oracle parameterized-query

我遇到了一个问题,我不知道我应该如何传入一个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是否在参数周围添加单引号?为什么不在第二种情况下添加引号呢?

2 个答案:

答案 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子句。