.net sql查询中的Oracle参数 - ORA-00933:SQL命令未正确结束

时间:2014-07-01 04:00:21

标签: sql oracle odp.net

我正在尝试创建一个where子句作为参数传递给Oracle命令,并且证明它比我想象的要困难。我想要做的是根据我们的应用程序的用户输入创建一个大的where查询。查询将成为语句的单个参数,并且其中包含多个AND,OR条件。这里的代码不是我需要的:

string conStr = "User Id=testschema;Password=pass12341;Data Source=orapdex01";
Console.WriteLine("About to connect to Database with Connection String: " + conStr);
OracleConnection con = new OracleConnection(conStr);
con.Open();
Console.WriteLine("Connected to the Database..." + Environment.NewLine + "Press enter to continue");
Console.ReadLine();

// Assume the connection is correct because it works already without the parameterization
String block = "SELECT * FROM TEMP_VIEW WHERE NAME = :1";

// set command to create anonymous PL/SQL block
OracleCommand cmd = new OracleCommand();

cmd.CommandText = block;
cmd.Connection = con;

// since execurting anonymous pl/sql blcok, setting the command type
// as text instead of stored procedure
cmd.CommandType = CommandType.Text;

// Setting Oracle Parameter
// Bind the parameter as OracleDBType.Varchar2 
OracleParameter param = cmd.Parameters.Add("whereTxt", OracleDbType.Varchar2);
param.Direction = ParameterDirection.Input;

param.Value = "MY VALUE";

// Get returned values from select statement
OracleDataReader dr = cmd.ExecuteReader();

// Read the identifier for each  result and display it
while (dr.Read()) 
{
    Console.WriteLine(dr.GetValue(0));
}

Console.WriteLine("Selected successfully !");
Console.WriteLine("");

Console.WriteLine("***********************************************************");

Console.ReadKey();

如果我将下面的行更改为我想要的结果类型,那么我会收到错误“ORA-00933:SQL命令未正确结束”:

String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";

我的问题是如何动态添加我的big where查询而不会导致此错误?

1 个答案:

答案 0 :(得分:1)

可悲的是,实现这一目标并不容易。

参数化SQL通常需要理解的一件事是绑定参数只能用于值,例如字符串,数字或日期。您不能在其中添加SQL,例如列名或WHERE子句。

一旦数据库具有SQL文本,它将尝试解析它并确定它是否有效,并且它将在不查看绑定参数值的情况下执行此操作。没有所有值,它将无法执行SQL。

SQL字符串SELECT * FROM TEMP_VIEW :1永远无效,因为Oracle不希望值立即跟随FROM TEMP_VIEW

您需要将SQL构建为字符串,并同时构建绑定参数列表。如果您发现需要在列NAME上添加条件,则将WHERE NAME = :1添加到SQL字符串和名称为:1的参数以及要添加的值。如果要添加第二个条件,则将AND ID = :2附加到SQL字符串和名为:2的参数。

希望以下代码可以更好地解释一下:

// Initialise SQL string and parameter list.
String sql = "SELECT * FROM DUAL";
var oracleParams = new List<OracleParameter>();

// Build up SQL string and list of parameters.
// (There's only one in this somewhat simplistic example.  If you have
// more than one parameter, it might be easier to start the query with
// "SELECT ... FROM some_table WHERE 1=1" and then append
// " AND some_column = :1" or similar.  Don't forget to add spaces!)
sql += " WHERE DUMMY = :1";
oracleParams.Add(new OracleParameter(":1", OracleDbType.Varchar2, "X", ParameterDirection.Input));

using (var connection = new OracleConnection() { ConnectionString = "..."})
{
    connection.Open();

    // Create the command, setting the SQL text and the parameters.
    var command = new OracleCommand(sql, connection);
    command.Parameters.AddRange(oracleParams.ToArray());

    using (OracleDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            // Do stuff with the data read...
        }
    }
}