Can anyone see why this SQL insert will not work? (Exception to String and Date to String Inserted) - JDBC - sql

Im trying to basically make a log of errors generated from a Java program and save them in an SQL table with 2 colums( Error and Date )
Try and catch sends the error to the method which should hopefully insert into database but its failing somewhere. Im new enough to Java so im not sure how to debug it properly or get more details on wahts going wrong and where
Heres the method.
public void createErrorLog(Exception error) throws SQLException{
// Error as String
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
error.printStackTrace(pw);
sw.toString(); // stack trace as a string
String errorOne = sw.toString();
System.out.println(errorOne);
// Date
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
String dateString = dateFormat.format(date);
Connection conn = null;
try {
conn = DriverManager.getConnection(CONN_STRING, USERNAME, PASSWORD);
System.out.println("Connected to database.");
String insertSaleProperty = "INSERT INTO ErrorLogs"
+ "(Error, "
+ "Time, "
+ "(?,?)";
PreparedStatement preparedStatement = conn.prepareStatement(insertSaleProperty);
preparedStatement.setString(1, errorOne);
preparedStatement.setString(2, dateString);
// execute insert SQL statement
preparedStatement.executeUpdate();
} catch (SQLException e) {
System.err.println("Cannot write to database.");
} finally {
if(conn != null){
conn.close();
}
}
}

Try the following.
String insertSaleProperty = "INSERT INTO ErrorLogs"
+ "(Error,Time) values "
+ "(?,?)";

String insertSaleProperty = "INSERT INTO ErrorLogs"
+ "(Error, "
+ "Time, "
+ "(?,?)";
Should probably be:
String insertSaleProperty = "INSERT INTO ErrorLogs "
+ "(Error, Time) "
+ "VALUES (?,?)";

Related

Creating Trigger to auto-increment id by sequence in JDBC

I am writing methods through JDBC to create a table and a sequence to recall in a Trigger, I want to set up an id column which auto-increments before every insert on the table. I succeeded in building both the createTable method and the createSequence method in the DAO, but when I run the method to create the Trigger I got the java.sql.SQLException: Missing IN or OUT parameter at index:: 1
public void createTrigger() {
PreparedStatement ps;
StringBuilder queryTrigger = new StringBuilder();
queryTrigger.append("CREATE OR REPLACE TRIGGER ");
queryTrigger.append(Tables.getInstance().getName() + "_INSERTED\n");
queryTrigger.append("BEFORE INSERT ON " + Tabelle.getInstance().getName());
queryTrigger.append("\nFOR EACH ROW\n");
queryTrigger.append("BEGIN\n");
queryTrigger.append("SELECT " + Tables.getInstance().getName() + "SEQ.NEXTVAL\n");
queryTrigger.append("INTO :new.id\n");
queryTrigger.append("FROM dual;\n ");
queryTrigger.append("END;\n");
queryTrigger.append("/\n");
queryTrigger.append("ALTER TRIGGER " +Tabelle.getInstance().getName() + "_INSERTED ENABLE\n");
queryTrigger.append("/\n");
String stringQueryTrigger = queryTrigger.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(stringQueryTrigger);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);}
Here instead the creation of the table does actually work even if I don't
write the classic lines with parametrized "?" for the preparedStatement.setString(index, String)
public void createTable(Columns c) {
PreparedStatement ps;
StringBuilder query = new StringBuilder();
query.append("CREATE TABLE " + Tabelle.getInstance().getName() + "(");
query.append(Columns.getInstance().getColumnName() + " ");
query.append(Columns.getInstance().getDataType());
if(Columns.getInstance().isNullOrNot() == true) {
query.append(" NOT NULL");
}
else {
query.append("");
}
if(Columns.getInstance().isPrimaryKeyOrNot() == true) {
query.append(" PRIMARY KEY)");
}
else {
query.append(")");
}
String queryToString = query.toString();
Connection conn = JDBCUtility.openConnection();
try {
ps = (PreparedStatement) conn.prepareStatement(queryToString);
ps.executeUpdate();
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
JDBCUtility.closeConnection(conn);
}
//EDIT
turns out that is enough to substitute the PreparedStatement with a simple Statement, to get rid of the indexes mechanism and get the DB to accept the query
I would suggest creating an auto-increment sequnce in oracle that can be used for all ids and just add the string id.NextVal to the string query
What I mean is:
Rem in oracle create sequence
CREATE SEQUENCE ID
START BY 1
INCREMENT 1
// in java to execute query
String query = "INSERT INTO TABLE VALUES(ID.NEXTVAL);" ;
//rest of code

Unable to set data to textField from tableView - on Mouseclick and Up and Down Arrow keys (H2 Database)

I am a recent user of the h2 database, I need some assistance with the SQL syntax.
I'm able to retrieve data from the h2 dB and set it into JavaFX tableView, On performing the mouseclick or buttonpress action (Up & Down arrows) the intended behaviour is to display the current row of data from the tableView into the textfields, below is the code.
I'm getting the following exception:
Invalid value "1" for parameter "parameterIndex" [90008-193]
I'm certain this exception is due to SQL grammar unique to the H2 database, as the placeholder (' "+slnoField.getText()+" ' ") works fine in other databases. Please could you suggest the correct syntax or a solution. Many thanks.
#FXML
public void UpdateTable(){
data.clear();
try
{
conn = lrconn.getDatabaseConnection();
String sql = "SELECT * from APP_TABLE ;
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next())
{
data.add(new TestPOJO(
rs.getString("SLNO"),
rs.getString("NAME")
));
Table.setItems(data);
}
pst.close();
rs.close();
}
catch(Exception e1)
{
e1.printStackTrace();
}
Table.setOnMouseClicked((MouseEvent me) ->{
try{
conn = lrconn.getDatabaseConnection();
TestPOJO user = (TestPOJO)Table.getSelectionModel().getSelectedItem();
String sql = "SELECT * from APP_TABLE where SLNO =' "+slnoField.getText()+" ' ";
pst = conn.prepareStatement(sql);
pst.setString(1, user.getSLNO());
rs = pst.executeQuery();
while(rs.next()){
slnoField.setText(rs.getString("SLNO"));
nameField.setText(rs.getString("NAME"));
}
rs.close();
pst.close();
}catch(SQLException ex){
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
);
Table.setOnKeyReleased((KeyEvent e) ->{
if(e.getCode() == KeyCode.UP || e.getCode() == KeyCode.DOWN){
try{
TestPOJO user = (TestPOJO)Table.getSelectionModel().getSelectedItem();
String sql = "SELECT * from APP_TABLE where SLNO =' "+slnoField.getText()+" ' ";
pst = conn.prepareStatement(sql);
pst.setString(1, user.getSLNO());
rs = pst.executeQuery();
while(rs.next()){
slnoField.setText(rs.getString("SLNO"));
nameField.setText(rs.getString("NAME"));
catch(IOException | SQLException ex){
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
);
}
You're not using the PreparedStatement correctly. Place ? at locations where you want to insert parameters in the query string. You don't seem to add one of those:
String sql = "SELECT * from APP_TABLE where SLNO = ?";
pst = conn.prepareStatement(sql);
pst.setString(1, user.getSLNO());
rs = pst.executeQuery();

PreparedStatement SetString doesn't work (case Oracle)

I don't have an idea why this method gets an error
public TdPegawai getTdPegawai(String nip) throws Exception {
PreparedStatement ps = null;
try {
TdPegawai tp = new TdPegawai();
sql = "select * "
"from TD_PEGAWAI " +
"where NIP=? ";
ps = connection.prepareStatement(sql);
ps.setString(1, nip);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
// tp.setblablabla();
}
rs.close();
return tp;
} finally {
ConnectionUtil.closePreparedStatement(ps);
}
}
My SQL variable just returns SELECT * FROM TD_PEGAWAI WHERE NIP=?
My nip variable can return a value.
Is there any something wrong with my preparestatement or setstring ?

Oracle vs Oracle ODBC

The following code works fine from within Oracle's SqlPlus (using Oracle 11.2.02.0g) however when I connect with and ODBC connection via C# code, I get told I have an invalid character.
Since the single quote didn't work in SQLplus, I'm assuming the characters that are consider invalid by ODBC are the double quotes. I've tried braces '{' and brackets '[' but still get the same error -> ERROR [HY000][Oracle][ODBC][Ora]ORA-00911:invalid character <-
Any help would be much appreciated. I still don't understand why SQL statements would be interpreted differently because of the connection type.
CREATE USER "AD1\EGRYXU" IDENTIFIED EXTERNALLY;
Error if ran alone that states the username conflicts with another user or role name. It does create the user in the database.
C# Code is below.
private void button1_Click(object sender, EventArgs e)
{
string happy = "";
string sql1 = "";
string sql2 = "";
string sql3 = "";
string sql4 = "";
string column;
int rownum = -1;
bool frst = false;
string dirIni = "\\\\ramxtxss021-f01\\hou_common_013\\globaluser\\";
string fileIni = "add_users.sql";
string transIniFullFileName = Path.Combine(dirIni, fileIni);
System.Data.Odbc.OdbcConnection conn = new System.Data.Odbc.OdbcConnection();
num_users = (usrdetails.Count > 0);
if (regions && num_users)
{
using (StreamWriter sw = new StreamWriter(transIniFullFileName))
{
for (int y = 0; y < usrdetails.Count; y++)
{
switch(usrdetails[y].add_del.ToUpper())
{
case "A":
sql1 = "CREATE USER \"" + usrdetails[y].userID.ToUpper() + "\" IDENTIFIED EXTERNALLY;";
sql2 = "GRANT EDMROLE TO \"" + usrdetails[y].userID.ToUpper() + "\";";
sql3 = "INSERT INTO MD_SITE_USER VALUES(generate_key(5), (select user_id from MD_SITE_USER where user_name = '" +
usrdetails[y].group + "') , {" + usrdetails[y].userID.ToUpper() + "}, " + usrdetails[y].seclev +
", '" + usrdetails[y].username.ToUpper() + "', 'U', '" + usrdetails[y].isext.ToUpper() + "', 'N');";
sw.WriteLine(sql1);
sw.WriteLine(sql2);
sw.WriteLine(sql3);
break;
case "D":
sql2 = "DELETE MD_SITE_APP_ACTION_OWNER WHERE user_id in (SELECT user_id FROM MD_SITE_USER where user_name = ‘"+ usrdetails[y].userID + "’+ and user_or_group = ‘U’);";
sql3 = "DELETE FROM MD_SITE_USER where user_name = ‘"+ usrdetails[y].userID + "’ and user_or_group = ‘U’;";
sql4 = "DROP USER "+ usrdetails[y].userID + " FROM USERS;";
sw.WriteLine(sql2);
sw.WriteLine(sql3);
sw.WriteLine(sql4);
break;
default:
MessageBox.Show("Add/Delete command argument not recognized for user\r\n" + usrdetails[y].userID + " \r\n Argument -> " + usrdetails[y].add_del);
break;
}
}
sw.Close();
}
for (int x = 0; x < region.Count; x++)
{
OdbcCommand command = new OdbcCommand();
conn.ConnectionString = "Driver={Oracle in OraClient11g_home1};" +
"Dbq=" + region[x].dbname +
";Uid=" + region[x].username + ";Pwd=" + region[x].password + ";";
try
{
string cmdTexts = File.ReadAllText(transIniFullFileName);
conn.Open();
using (conn)
{
command.Connection = conn;
command.CommandText = cmdTexts;
command.ExecuteNonQuery();
OdbcDataReader dr = command.ExecuteReader();
Form6.dataGridView2.AutoGenerateColumns = false;
if (!frst)
{
for (int i = 0; i < dr.FieldCount; i++)
{
column = dr.GetName(i);
Form6.dataGridView2.Columns.Add("col" + i, column);
Form6.dataGridView2.Columns[i].FillWeight = 1;
}
frst = true;
}
rownum++;
dataGridView1.Rows.Add();
dataGridView1.Rows[rownum].Cells[0].Value = "Results for Region -> " + Form5.region[x].dbname;
dataGridView1.Refresh();
while (dr.Read())
{
rownum++;
Form6.dataGridView2.Rows.Add();
for (int i = 0; i < dr.FieldCount; i++)
{
column = dr.GetValue(i).ToString();
Form6.dataGridView2.Rows[rownum].Cells[i].Value = column;
}
}
Form6.dataGridView2.Refresh();
Form6.dataGridView2.Show();
Form6.Show();
}
conn.Close();
Form6.dataGridView2.Refresh();
}
catch (Exception ex)
{
MessageBox.Show("Error Message: " + ex.Message);
}
}
}
else
{
if (!regions)
happy = "Error - You have not selected any regions.\r\n";
else
happy = "Regions are now selected.\r\n";
if (!num_users)
happy = happy + "Error - You have not entered any users.\r\n";
MessageBox.Show(happy);
}
File.Delete(transIniFullFileName);
}
Don't use ";" (semi-colon) in the command text..
The command text within ODBC or ODP should be a command, e.g. not a set of commands, therefore - ";" is not relevant, and is an invalid character.
it appears you are trying to run a script..
if that is your intent, it should be padded with a "begin" and "end" for the code to be able to run:
BEGIN
INSERT...;
DELETE ...;
END;
(refer to http://www.intertech.com/Blog/executing-sql-scripts-with-oracle-odp/ for more info)
Last thing - if you want to run a "create user" (or any other DDL) from within an anonymous block or a procedure you need to run it with "execute immediate" syntax:
BEGIN
execute immediate 'CREATE USER test IDENTIFIED EXTERNALLY';
END;

SQL Syntax error when using SQLCommand.EndExecuteNonQuery

I'm trying to run two SQL statements (MSSQL 2005), asynchronously in a background worker. However, when I call the EndExecuteNonQuery method on the first SqlCommand I get a 'SQL syntax error near' error.
Here is my code:
try
{
SqlCommand sqlCmd = uow.DataLayer.CreateCommand() as SqlCommand;
sqlCmd.CommandText = "DELETE FROM dbo.EligibilityRecordKeyValue WHERE EligibilityRecord IN " +
"(SELECT EligibilityRecord FROM dbo.EligibilityRecord WHERE Organization = '" + map.Organization.Oid + "')";
IAsyncResult result = sqlCmd.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
worker.ReportProgress(0, "Deleting existing record keys");
System.Threading.Thread.Sleep(200);
}
count = sqlCmd.EndExecuteNonQuery(result);
}
catch (SqlException ex)
{
}
catch (InvalidOperationException ex)
{
}
finally
{
worker.ReportProgress(2, String.Format("Existing {0} records keys deleted.", count));
}
try
{
SqlCommand sqlCmd = uow.DataLayer.CreateCommand() as SqlCommand;
sqlCmd.CommandText = "DELETE FROM dbo.EligibilityRecord WHERE Organization = '" + map.Organization.Oid + "'";
IAsyncResult result = sqlCmd.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
worker.ReportProgress(0, "Deleting existing records");
System.Threading.Thread.Sleep(200);
}
count = sqlCmd.EndExecuteNonQuery(result);
}
catch (SqlException ex)
{
}
catch (InvalidOperationException ex)
{
}
finally
{
worker.ReportProgress(5, String.Format("Existing {0} records deleted.", count));
}
It fails on the first count = sqlCmd.EndExecuteNonQuery(result);
Ok, adding WAITFOR DELAY's to both SQL commands seems to have resolved the issue.
sqlCmd.CommandText = String.Format("WAITFOR DELAY '00:00:05'; DELETE FROM dbo.EligibilityRecordKeyValue WHERE EligibilityRecord IN " +
"(SELECT EligibilityRecord FROM dbo.EligibilityRecord WHERE Organization = '{0}')", map.Organization.Oid);
sqlCmd.CommandText = String.Format("WAITFOR DELAY '00:00:05'; DELETE FROM dbo.EligibilityRecord WHERE Organization = '{0}'", map.Organization.Oid);
Anyone know why this happens?