【问题标题】:Passing in Oracle Parameter to SQL string将 Oracle 参数传递给 SQL 字符串
【发布时间】:2018-06-01 14:33:35
【问题描述】:

我遇到了一个问题,我不知道应该如何传入 C# 类型为 string 而 Oracle 类型为 Varchar2 的 Oracle 参数。

目前,我将这个string 作为CMS','ABC 传递,认为Oracle 将添加围绕这个string'',使其成为一个看起来像'CMS','ABC'varchar2

这适用于单个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 并带有引号时,下面的内容不起作用。

OracleParameter param = new OracleParameter(":names", OracleDbType.Varchar2, "CML','ABC", ParameterDirection.Input);

这是为什么呢?

Oracle 是否在将参数传递到 sql 语句时在参数周围添加单引号?为什么它不在第二种情况下添加引号?

【问题讨论】:

  • ODP.NET 不支持带有IN 子句的参数。见:stackoverflow.com/questions/1625649/…
  • :names 只是CML 时有效,因此它与IN 子句绑定得很好。
  • 嗯,是的,我上面的评论不太正确,我应该说:ODP.NET 参数不适用于多个逗号分隔值。

标签: c# sql oracle parameterized-query


【解决方案1】:

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?

【讨论】:

    【解决方案2】:

    从您的 cmets/answers 我能够想出这个解决方案。我希望它可以帮助其他来的人。

    要解决 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 子句。

    【讨论】:

      猜你喜欢
      • 2013-12-03
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多