I'm salvaging Java code left for me from the previous employee, I was only left with the source code itself, I've had to recreate DB structure by myself. So far I fully restored it, but one line always throws exceptions at me and I can't understand why.
connBeztirazh.execSQLU("declare #ki table (ID_ki int); " +
"declare #bil table (ID_bilet int); " +
"insert into ki (i1,i2,i3,i4,i5,i6) output inserted.ID_ki into #ki values ("+i1+","+i2+","+i3+","+i4+","+i5+","+i6+"); " +
"insert into bilet(ID_ki,data) output inserted.ID_bilet into #bil values ((select ID_ki from #ki),(select SYSDATETIME())); " +
"insert into rezultat (ID_players, ID_bilet) output inserted.ID_bilet values ((select ID_players from players where telnomer='"+number+"'),(select ID_bilet from #bil));", false);
This line throws out the following exception:
com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'ki'.
I triple-checked everything, I recreated tables bilet, players and rezultat, they are used elsewhere in the code and everything's alright. As far as I understand SQL, ki and bil are temporary tables and since they are created and accessed in the same query there could not be any access/session problems.
In this case, I overlooked that in fact there are two tables: constant table ki and variable table ki. They are referenced by ki and #ki respectively, which is a really bad way to name your tables. After adding table ki to the database, everything started working as intended, as far as I can tell.
Thanks to everyone who commented on the post.
Related
I have a program in JAVA which creates a table in a database and then I insert rows in this table.
The table is created as below:
String sql = "CREATE TABLE IF NOT EXISTS weather (\n"
+ " city string,\n"
+ " temp real,\n"
+ " feels_like real,\n"
+ " temp_min real,\n"
+ " temp_max real,\n"
+ " pressure integer,\n"
+ " humidity integer\n"
+ ");";
When I add rows, I don't want to have duplicates for the field named "city".
So, for example, if I already have London with its data, I don't want to add it again, even though that all its data may have changed. I want to have it only once in my table.
I have this query for insertion :
String sql = "INSERT INTO weather VALUES(?,?,?,?,?,?,?);";
and I want to modify it so I don't insert city duplicates.
Can anyone help me please? Thanks!
If the version of SQLite you use is 3.24.0+ and there is a unique constraint for the column city, you can use upsert which gives you an option to do NOTHING or UPDATE the table if a unique constraint violation occurs.
In this case:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT DO NOTHING";
if you try to insert a row with an existing city, the statement will fail without an error.
But if the new row contains up to date data for the other columns and you want the row updated, you can do this:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT(city) DO UPDATE SET "
"temp = excluded.temp, " +
"feels_like = excluded.feels_like, " +
"temp_min = excluded.temp_min, " +
"temp_max = excluded.temp_max, " +
"pressure = excluded.pressure, " +
"humidity = excluded.humidity";
and the other 6 columns will be overwritten by the new values you supplied.
If there isn't a unique constraint defined for city and you don't want to or can't define one, then you can avoid inserting the same city twice with NOT EXISTS like this:
String sql =
"INSERT INTO weather SELECT ?,?,?,?,?,?,? " +
"WHERE NOT EXISTS (SELECT 1 FROM weather WHERE city = ?);
In this case you will have to pass in your Java code as an additional 8th parameter the value of the city again.
There is no way to do this in 'effectively standard SQL'*.
But, each individual DB engine does usually have some way of accomplishing this goal.
The concept is called merging or upserting - those are terms you can search the web for. Just search for 'how to postgres upsert' for example. It's called upsert because the more general application is: If some subset of the values I am inserting doesn't exist yet in the DB, INSERT a new row with this data. Otherwise, find the row with the same values for this subset, and then update all the other values with it. For example: "Find the student with ID 12345, and then change the name to 'Joe Bloggs'. If there is no row with that, then make it".
make ALL the values 'the key' and you've reduced your 'insert, ignore if it is already there' to a standard UPSERT.
In psql, you can do ON CONFLICT. searching for 'mysql upsert' gets you to blog posts that give you varying tactics depending on your exact needs, from using INSERT IGNORE (I advice against this, this ignores any and all errors, vs only ignoring the 'already in here' error only), ON DUPLICATE KEY UPDATE (better idea, this), or using REPLACE.
Similar blog posts will be found for any db engine you are using here.
*) Defined not as 'as per some version of the SQL standard', but defined as: 'works in the majority of existing DB engines'.
You can now use on conflict. This requires that you have a unique index/constraint on city but it is already defined as the primary key. Check.
insert into weather ( . . . )
values ( . . . )
on conflict (city) ignore;
SQLite also allows this shorthand:
insert or ignore into weather ( . . . )
values ( . . . );
I have some problems with my code. I want to extract the column names from my table. Everything works fine in mySQLWorkbench and it shows me all of my column names.
For example the output in mySQL Workbench is : nr,height,length
The output on my oracle database is: nr,height,length,nr,height,length,...
it looks like I'm in a loop, but I cant understand why. The oracle database is located at my university, so I can't get any access to work with it like mySQLWorkbench.
I tried this code below and at the moment i really dont know what to do.
ResultSet columns = databaseMetaData.getColumns(null,null, tableName, null);
while(columns.next())
{
String columnName = columns.getString("COLUMN_NAME");
System.out.println(columnName + ";");
}
in my opinion the output should be: nr;height;length
What I have are 7 tables, one of which is a master list and the other 6 are archives. Also, the archives are on another database. I need to go through the archive tables and delete rows, by checking 3 different column IDs (top, middle, bottom) that are not listed in the master table, as they are not relevant anymore. My SQL statement is below. I don't have a way to test it yet, but since I am not very familiar with SQL I was hoping people could give a few tips.
String[] tables;
tables = new String[]{"archive1", "archive2", "archive3",
"archive4", "archive5", "archive6"};
String query;
Statement stmt;
String objs = "TOP AND MIDDLE AND BOTTOM";
while(i<tables.length){
//TODO: CONFIRM THE QUERY IS CORRECT
query = "DELETE FROM "+ tables[i] + " WHERE "+ objs +
"NOT IN(SELECT " + objs + " FROM DB.masterTable WHERE " +
objs + " IS NOT NULL)";
//IS NOT NULL may not be necessary
try{
//TODO: VERIFY CONNECTION IS CORRECT
stmt = this.DB2.createStatement();
stmt.executeUpdate(query);
}catch(SQLException x){
System.out.println("Failure in loop queries!");
}
i++;
}
}
In the tables there are many columns, but I am concerned with comparing the top, middle, and bottom IDs (together they are unique to each row, but e.g. top might have many of the same values). So like I said, if there isn't a row with the same TOP, MIDDLE, BOTTOM in the master table, OBJECTS, then that row can be deleted from the archive that has it listed. I tried to put everything in one query but maybe I need multiple?
My main questions are:
A) Is my query correct in any sense?
B) Since the tables are on 2 different databases how should I handle that?
Solution found:
query = "DELETE FROM "+ tables[i] +
" WHERE (TOP, MIDDLE, BOTTOM) NOT IN "+
"(SELECT TOP, MIDDLE, BOTTOM FROM DB1.DB.masterTable)";
Main problem became figuring out how to compare all 3 fields of each row at a time and accessing the DB tables
A) No. There are some fundamental errors in your query. If you expand out your query, where objs = "OBJ_ID_TOP AND OBJ_ID_MIDDLE AND OBJ_ID_BOTTOM"
query = "DELETE FROM "+ tables[i]
+ " WHERE OBJ_ID_TOP AND OBJ_ID_MIDDLE AND OBJ_ID_BOTTOM
NOT IN(SELECT OBJ_ID_TOP AND OBJ_ID_MIDDLE AND OBJ_ID_BOTTOM
FROM db1Connection.OBJECTS
WHERE OBJ_ID_TOP AND OBJ_ID_MIDDLE AND OBJ_ID_BOTTOM IS NOT NULL)";
This is not proper SQL... If we take a glance at the wiki page on the WHERE clause,
The proper syntax for writing SQL Where clause is
SELECT <> FROM table WHERE column operatorvalue
Use AND and OR to string up multiple column conditions in your WHERE clause.
Also, AND is not valid in a SELECT statement. If you want to combine multiple result sets, use UNION.
Something of the form (see below) is closer to what you need. (Note: it is not optimized by any means... just a demonstration)
EDIT Think I originally misunderstood what you were trying to do... but I think you want to delete from some_table, not master_table.
--DELETE --can swap out SELECT for DELETE when the selected results look right
SELECT s.*
FROM some_table s --this is table[i]
LEFT OUTER JOIN master_table mt --db1Connection.OBJECTS
on s.ID_TOP = mt.ID_TOP
AND s.ID_MIDDLE = mt.ID_MIDDLE
AND s.ID_BOTTOM = mt.ID_BOTTOM
WHERE mt.ID_TOP IS NULL
AND mt.ID_MIDDLE IS NULL
AND mt.ID_BOTTOM IS NULL
B) I can't help you with this question... someone with more DB2(?) chops can help you
You need to get the list of data to be deleted from the first DB.
Then go for deletion in the second DB
And, you just can't compare saying obj1 and obj2 and obj3 not in (some list), it should be like obj1 not in (somelist) and obj2 not in (somelist) and obj3 not is(whatever).
In this case, it would be a good idea to create a temp table in DB2 where the archive tables are, with data from the master table in DB1. Then, run queries like
delete from archive1 where col1 not in (select col_master from temp_table);
how to create user defined table (table name is in a string ) oracle using java
String Tablename="student";
stmt=con.prepareStatement("create table"+Tablename+"(name varchar(12),class varchar(12))");
stmt.executeUpdate();
with out string i.e user defined table name it works fine:
stmt=con.prepareStatement("create table student (name varchar(12),class varchar(12))");
but the above listed versions which takes string as user name shows following error
java.sql.SQLException: ORA-00901: invalid CREATE command
Leave spaces before and after the table name, please.
Your original code resulted in this SQL command getting executed:
create tableMyTablename(name varchar(12),class varchar(12))
And in that, the tableMyTablename was not comprehensible for the DB...
Correctly:
stmt=con.prepareStatement("create table "+Tablename+" (name varchar(12),class varchar(12))");
Also, a few notes:
Java naming: variable names start with lowercase letters
this (preparing the statement) doesn't really make sense. It is not reusable to have a statement that can only create the same structure for a table.
it is wise to avoid the + to concatenate Strings, and other objects' string representations... It may have very unexpected results, even compile errors...
logging: in such situations, it is always wise to log the created SQL commands. Even a (yuck!) System.out.println(); is better than nothing...
Put a space after "create table" i.e.
"create table "
Your statement was being evaluated as create tablestudent...
I am trying to use a Java application (which I do not have the source code for) to output the results of a call to a stored procedure into a text file.
This file works for other similar stored procedures in the system, but I can't seem to get it to produce anything for my new text file other than this exception:
ResultSet is from UPDATE: No Data
I've simplified the body of the stored procedure to a simple select 'Hello World!' and even that doesn't seem to be able to be written out.
Is there anything I can do within the stored procedure to produce results in a fashion that Java will accept?
I encountered this java.sql.SQLException. In my case I was running a query in this way:
String query =
"-- a classical comment " +
"select * " +
"from MYTABLE ";
ResultSet rs = conMain.createStatement().executeQuery(query);
while(rs.next()) {
//do something...
}
rs.next() throws the exception. The reason is that, due to the comments, query results to be:
"-- a classical comment select * from MYTABLE "
hence it's all commented... query is invalid! Many examples could be shown with this mistake (with the comment in the middle of the query etc.).
Solutions: add a \n at the end of each line of the query or use comments in the /*...*/ form.
I selected an older version of the driver an it worked for me.
http://dev.mysql.com/downloads/mirror.php?id=13598 (mysql-connector-java-5.0.8.zip)