我正在尝试创建一个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查询而不会导致此错误?
答案 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...
}
}
}