将 Oracle 参数传递给 SQL 字符串

Passing in Oracle Parameter to SQL string

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

目前我将此 string 作为 CMS','ABC 传递,认为 Oracle 将添加 '' 围绕此 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 且内部带有引号时,以下内容不起作用。

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

这是为什么?

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

ODP.NET 参数不适用于多个逗号分隔值。每个参数都被视为单个值,无论它包含哪种引号。

Oracle 在传递给查询时不会在参数值周围添加引号。引号只是在查询中写入 VARCHAR 值的一种方式,但在使用参数时,Oracle 不会 "replace your parameter with its value then execute the query",因为这将允许 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?

从您的 comments/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 子句。