将 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
子句。
我遇到了一个问题,我不知道如何传递 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
子句。