result of an oracle command - sql

I'm doing a graphical user interface using Windows Form Application, using an oracle database.
I'm trying to bind to a label in my UI the result of an oracle command.
This is my code :
OracleCommand cmd = conn.CreateCommand();
string city = comboBox1.SelectedItem.ToString();
cmd.CommandText ="select c.companynum,c.namec from flight f, company c where f.companynum=c.companynum AND f.name1=&param1 order by f.name1;";
cmd.Parameters.AddWithValue("param1", city);
cmd.Parameters.Add("result", OracleType.VarChar, 200);
cmd.Parameters["result"].Direction = ParameterDirection.ReturnValue;
try
{
cmd.ExecuteNonQuery();
if (cmd.Parameters["result"].Value.ToString() == "")
label2.Text = "No destinations.";
else
label2.Text = cmd.Parameters["result"].Value.ToString();
da.SelectCommand.Parameters.Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception Caught");
}
But when it runs there's an exception : ORA-01036 : illegal variable name/number.
I don't know how to fix my code ?
NB : For my homework I have to use here the '&' method.

maybe it is done a little misunderstanding.. :)
I think that the original trace of your homework intended to that it should create a stored procedure where put into the select sql statement that you have passed to the command.
Stored proc should have 2 parameters: "city" and "result" ;)
Good homework!

Related

How to solve "ORA-00933 & ORA-00936" in SQL/Oracle?

Im creating a student profile for our project in school and it's my first time to make this.
This is my query for my jTable (mouseclicked) I've created in netbeans
int row = jTable1.getSelectedRow();
String tc = jTable1.getModel().getValueAt(row, 0).toString();
try {
String query ="select * from CAREPOINT_STUDENT where NAME="+tc+" ";
pst= (OraclePreparedStatement) ungabelio1.prepareStatement(query);
rs = (OracleResultSet) pst.executeQuery();
if(rs.next()){
String NAME_ID = rs.getString("NAME");
String AGE_ID = rs.getString("AGE");
String ADDRESS_ID = rs.getString("ADDRESS");
String NUM_ID = rs.getString("NUM");
String COURSE_ID = rs.getString("COURSE");
String SPECIAL_ID = rs.getString("SPECIAL");
String SCHOOL_ID = rs.getString("SCHOOL");
String DOWNPAY_ID = rs.getString("DOWNPAY");
String DISCOUNT_ID = rs.getString("DISCOUNT");
String BALANCE_ID = rs.getString("BALANCE");
String REVSCHED_ID = rs.getString("REVSCHED");
String EMAIL_ID = rs.getString("EMAIL");
NAME.setText(NAME_ID);
AGE.setText(AGE_ID);
ADDRESS.setText(ADDRESS_ID);
NUM.setText(NUM_ID);
COURSE.setText(COURSE_ID);
SPECIAL.setText(SPECIAL_ID);
SCHOOL.setText(SCHOOL_ID);
DOWNPAY.setText(DOWNPAY_ID);
DISCOUNT.setText(DISCOUNT_ID);
BALANCE.setText(BALANCE_ID);
REVSCHED.setText(REVSCHED_ID);
EMAIL.setText(EMAIL_ID);
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
When I run the program and tried to click the data (A Student Profile like name,age,school, etc..) that I created and printed inside the jtable (mouseclicked), I get this problem "ORA-00933: SQL command not properly ended"
Aside from that, I also have another problem which I created 2 jbutton called "DELETE" which means it will delete the data(Student profile) that I filled up and "UPDATE" which means to reedit the data(Student profile) that I filled up.
this is the query of my "DELETE" jbutton in netbeans
try {
String query;
query = "DELETE FROM CAREPOINT_STUDENT where NAME="+NAME.getText()+" ";
pst= (OraclePreparedStatement) ungabelio1.prepareStatement(query);
pst.execute();
JOptionPane.showMessageDialog(null, "Successfully deleted!");
fetch();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
and this is the query of my "UPDATE" jbutton in netbeans
try {
String query;
query = "update CAREPOINT_STUDENT set AGE=?,ADDRESS=?,NUM=?,COURSE=?,SPECIAL=?,SCHOOL=?,DOWNPAY=?,DISCOUNT=?,BALANCE=?,REVSCHED=?,EMAIL=? where NAME="+NAME.getText()+"";
pst= (OraclePreparedStatement) ungabelio1.prepareStatement(query);
pst.setString(1,AGE.getText());
pst.setString(2,ADDRESS.getText());
pst.setString(3, NUM.getText());
pst.setString(4, COURSE.getText());
pst.setString(5, SPECIAL.getText());
pst.setString(6, SCHOOL.getText());
pst.setString(7, DOWNPAY.getText());
pst.setString(8, DISCOUNT.getText());
pst.setString(9, BALANCE.getText());
pst.setString(10, REVSCHED.getText());
pst.setString(11, EMAIL.getText());
pst.executeUpdate();
JOptionPane.showMessageDialog(null, "Successfully updated!");
fetch();
} catch (Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
when I run the program and click those 2 buttons, I get the same problem "ORA-00936: missing expression"
I really appreciate and I hope that somebody would help me to fix this problem. So that I can gain some little knowledge about sql/oracle.
Sorry for my bad english.
Avoid concatenating parameters as strings; use prepared statements.
Otherwise you'll run in all kind of troubles, like escaping issues for special characters, SQL Injection, etc.
For example, a safer way of running your SQL statement could be:
String query = "select * from CAREPOINT_STUDENT where NAME = ?";
pst = (OraclePreparedStatement) ungabelio1.prepareStatement(query);
pst.setString(1, tc);
rs = (OracleResultSet) pst.executeQuery();
Note: Assembling a SQL statement as a string is still useful for cases when you want to do some dynamic SQL. Even then, use ? for parameters and apply them as shown above.
You may need some extra single quotes so you query will read:
select * from CAREPOINT_STUDENT where NAME='Entered name';
Adjust your code:
String query ="select * from CAREPOINT_STUDENT where NAME='"+tc+"' ";

SQL Command not properly ended Exception

Pretty basic sql Command. Just want to get the count from different tables I am looping through. However, if I alter the sqlCommand and add a ';' at the end I get exception, SQL command not properly ended.
sqlCommand = String.Format("SELECT COUNT(1) FROM SO.{0} where DR_ADDRESS_ID = {1};", table, drAddr);
I am curious why this semi-colon makes this exception thrown since commands are suppose to end with a ';'
sqlCommand = String.Format("SELECT COUNT(1) FROM SO.{0} where DR_ADDRESS_ID = {1}", table, drAddr);
try
{
using(OracleCommand ocCommand = new OracleCommand(sqlCommand,CommandType.Text))
{
ocCommand.Connection = dbConnection;
recordCounter = Convert.ToInt64(ocCommand.ExecuteScalar());
}
}
catch (Exception er)
{
MessageBox.Show(String.Format("Error in RecordCount for table {0}: Reference {1} for log. err = {2}",table, logFilePath,er.ToString()));
recordCounter = -1;
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
writer.WriteLine(String.Format("Table: {0}. Command {1}", table,sqlCommand.ToString()));
}
}
Semi colons are usually just used as a command terminator for interactive tools like sqlplus.

Oracle Parameters in .net sql queries - ORA-00933: SQL command not properly ended

I am trying to do create a where clause to pass as a parameter to an Oracle command and it's proving to be more difficult than I thought. What I want to do is create a big where query based off user input from our application. That where query is to be the single parameter for the statement and will have multiple AND, OR conditions in it. This code here works however isn't exactly what I require:
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();
If I change the lines below to be the type of result I want then I get an error "ORA-00933: SQL command not properly ended":
String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";
My question is how do I accomplish adding my big where query dynamically without causing this error?
Sadly there is no easy way to achieve this.
One thing you will need to understand with parameterised SQL in general is that bind parameters can only be used for values, such as strings, numbers or dates. You cannot put bits of SQL in them, such as column names or WHERE clauses.
Once the database has the SQL text, it will attempt to parse it and figure out whether it is valid, and it will do this without taking any look at the bind parameter values. It won't be able to execute the SQL without all of the values.
The SQL string SELECT * FROM TEMP_VIEW :1 can never be valid, as Oracle isn't expecting a value to immediately follow FROM TEMP_VIEW.
You will need to build up your SQL as a string and also build up the list of bind parameters at the same time. If you find that you need to add a condition on the column NAME, you add WHERE NAME = :1 to the SQL string and a parameter with name :1 and the value you wish to add. If you have a second condition to add, you append AND ID = :2 to the SQL string and a parameter with name :2.
Hopefully the following code should explain a little better:
// 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...
}
}
}

how to use 'try catch finally' block to display message when mysql query is executed successfully

I have been using a 'try catch finally' in the code for a C# Windows form to query a MySQL database. The code works well: when the catch block flags errors, a message box will display error messages.
In the finally block, I coded a message box that will show when the database is successfully updated.
If there is no error message it all works well. The success message shows.
But if there is an error, the error message in the catch block is displayed, followed by the success message in the finally block.
Does anyone know a solution to get a program to display either an error message or a success message when mysql is updated?
Thanks,
Peter
Here is a code sample:
private void btnUpdateEmployeeTable_Click(object sender, EventArgs e) //Update record in Employee table
{
String myConnection = #"server=localhost; database=shopdb; username=**; password=**; convert zero datetime=True";
MySqlConnection Connect = null;
try
{
Connect = new MySqlConnection(myConnection);
Connect.Open(); //Open the connection
//This is the mysql command that we will query into the db.
//It uses Prepared statements and the Placeholders for faster, more secure processing.
String updateQuery = "UPDATE employee SET emp_lName = #empLastName, emp_fName = #empFirstName WHERE emp_number = #empNum";
MySqlCommand cmdInsertEmployeeToDataBase = new MySqlCommand(updateQuery, Connect);
cmdInsertEmployeeToDataBase.Prepare();
//Bind the value to the placeholder
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empNum", this.txtEmployeeNo.Text);
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empLastName", this.txtEmployeeLastName.Text);
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empFirstName", this.txtEmployeeFirstName.Text);
cmdInsertEmployeeToDataBase.ExecuteNonQuery(); //Execute the mysql command
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\nDatabase could not be updated \n" + "Please try again");
}
finally
{
if (Connect != null)
{
Connect.Close(); //Close the connection
}
MessageBox.Show("Database update successful");
}
}
You can easily move the success code up higher. If an exception is thrown before the MessageBox.Show("Database update successful"); line, then it will never get executed.
try
{
Connect = new MySqlConnection(myConnection);
Connect.Open(); //Open the connection
//This is the mysql command that we will query into the db.
//It uses Prepared statements and the Placeholders for faster, more secure processing.
String updateQuery = "UPDATE employee SET emp_lName = #empLastName, emp_fName = #empFirstName WHERE emp_number = #empNum";
MySqlCommand cmdInsertEmployeeToDataBase = new MySqlCommand(updateQuery, Connect);
cmdInsertEmployeeToDataBase.Prepare();
//Bind the value to the placeholder
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empNum", this.txtEmployeeNo.Text);
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empLastName", this.txtEmployeeLastName.Text);
cmdInsertEmployeeToDataBase.Parameters.AddWithValue("#empFirstName", this.txtEmployeeFirstName.Text);
cmdInsertEmployeeToDataBase.ExecuteNonQuery(); //Execute the mysql command
MessageBox.Show("Database update successful");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\nDatabase could not be updated \n" + "Please try again");
}
finally
{
if (Connect != null)
{
Connect.Close(); //Close the connection
}
}

SQL ERROR: The connection was not closed. The connection's current state is open

EDIT
After staring at this for 2 days, I do see one issue. I was still opening the original connection. So I changed the inner open statements to conn2.Open. Then, I changed the second inner query to where all the variables were number 3 instead of 2 so that they were completely different than the previous query. At that point, I got the error:
There is already an open DataReader associated with this Command which must be closed first.
I took out the inner connections, thinking I could use the outer connection and took out the inner .Close lines, but that also returned an error saying the connection was not closed.
END EDIT
I am writing a script that updates user information with data pulled from other tables where that user may be in it multiple times for purchases made.
So first, the "outside" sql query pulls some data from the items table which contains purchaser information as well as category information. For each item, it is going to check it's purchaser's information.
Second, the first "inner" sql query pulls category information from the user table. Some code is then run to see if they're already marked as purchasing from the category of the "outside" query. If they are not, it adds the category to a string variable.
Lastly, the second "inner" sql query updates the user table for the current user with the new category list.
I've asked about how to perform queries like this before, but was always given a solution of combining the queries into one. That worked for the other queries, but I cannot do that here. I must iterate through each record of the outer query to perform the necessary functions inside of it. But my issue here is that I get an SQL error saying that the connection was not closed, and it points to the catch of the outer query (for 'conn').
I had tried to set my 2 inner queries so that they used different connection variables (conn2 and conn3), and also different strSQL variables, but that didn't help. And I'm still a newb when it comes to SQL, having programmed using MySQL until this probject. Any help would be greately appreciated.
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionName"].ToString()))
using (SqlCommand strSQL = conn.CreateCommand())
{
strSQL.CommandText = "SELECT field FROM itemsTable";
try
{
conn.Open();
using (SqlDataReader itemReader = strSQL.ExecuteReader())
{
while (itemReader.Read())
{
{Do some stuff here}
using (SqlConnection conn2 = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionName"].ToString()))
using (SqlCommand strSQL2 = conn2.CreateCommand())
{
strSQL2.CommandText = "SELECT fields FROM userTable";
try
{
conn2.Open();
using (SqlDataReader itemReader2 = strSQL2.ExecuteReader())
{
while (itemReader2.Read())
{
{Do stuff here}
}
itemReader2.Close();
}
}
catch (Exception e3)
{
throw new Exception(e3.Message);
}
finally
{
conn2.Close();
}
}
{Do some more stuff here}
using (SqlConnection conn2 = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionName"].ToString()))
using (SqlCommand strSQL2 = conn2.CreateCommand())
{
strSQL2.CommandText = "UPDATE userTable set field='value'";
try
{
conn2.Open();
strSQL2.ExecuteNonQuery();
}
catch (Exception e2)
{
throw new Exception(e2.Message);
}
finally
{
conn2.Close();
}
}
{Do even more stuff here.}
}
itemReader.Close();
}
}
catch (Exception e1)
{
throw new Exception(e1.Message);
}
finally
{
conn.Close();
}
}
There's some unusual logic going on with conn.Open(). I see it used several times, but I think you mean to use conn2.Open() in the inner using statements after the first call.