I use UCanAccess (4.0.2) to create a new file with a single table like this:
// Create a database + connect
DatabaseBuilder.create(FileFormat.V2010, new File(path));
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
conn = DriverManager.getConnection("jdbc:ucanaccess://" + path + ";singleconnection=true" ,"", "");
// Create table
String sql = "CREATE TABLE Test (id AUTOINCREMENT PRIMARY KEY, value CHAR(1) NOT NULL)";
conn.createStatement().executeUpdate(sql);
The code works but the resulting table seems to be incomplete/flawed. Trying to copy it in Access results in an error:
'' is not a valid name...
Doesn't seem to be a big problem as saving the table from the design view solves it.
Any idea why that happens and how to avoid it?
This is related to a confirmed issue with Jackcess versions 2.1.8 and older. A fix has been applied to Jackcess that will be included in the next release (tentatively 2.1.9). Once a UCanAccess update is released that includes the Jackcess fix then the problem should go away.
Related
com.datastax.driver.core.Session
for example:
//This works
session.execute ("select * from table");
//This returns a nullpointer
session.execute ("create table testtable ( number int, string varchar)");
Do I have to use some sort of schema builder?
NOTE: im connected to the cassandra instance and can query it no problem. I just want to be able to create tables from the datastax driver
What error do you get when trying to CREATE a table?
As for some quick things to try, it's possible that your user might be missing the CREATE permission.
session.execute ("create table testtable ( number int, string varchar)");
Another thing I noticed about this statement, was that you don't seem to be specifying a PRIMARY KEY. All tables in Cassandra must have a primary key.
Try altering your CQL to this, and see if it helps:
create table testtable ( number int, string varchar, PRIMARY KEY (number))
I accidentally converted my database file to a text file. When opened, it shows that I am using the wrong encoding format. Any help would be highly appreciated.
File screenshot
I don't believe that you have because :-
Android Studio has no built-in support for browsing SQLite databases and hence why it shows as it does. It would probably look similar in NotePad.
That is there is little reason why you would open a database in Android Studio (or any other editor (unlesss it is one that supports SQLite files)).
To re-assure you, here's an SQLite database I opened in Android Studio (and goth the same message) :-
If you loaded the file into/opened the file in a tool for browsing/managing SQLite databases then I would expect that the database will be accessible.
Opening the above database in an App allows the App to output the following from the database :-
04-02 10:25:18.979 1837-1837/? D/OADB-HLPR: logDatabaseTableInformation initiated.
Database contains Table testtable created by SQL CREATE TABLE `testtable` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT,
`timestamp` INTEGER
)
Table is testtable Column Count = 3 Row Count = 2
Columns are :- _id name timestamp
Database contains Table sqlite_sequence created by SQL CREATE TABLE sqlite_sequence(name,seq)
Table is sqlite_sequence Column Count = 2 Row Count = 1
Columns are :- name seq
logDatabaseTableInformation completed.
As you can see a lot of the information matches the screenshot.
Likewise if you accessed the database in an app then again it very much looks as though it would be as expected.
From what is shown it appears that you have a table called QuestionBank, it has a column with a type of INTEGER PRIMARY KEY AUTOINCREMENT as table sqlite_sequence exists. etc.
I say this because the first characters are SQLite format 3 as per :-
0 16 The header string: "SQLite format 3\000"
Database File Format
One such tool that is commonly used is DB Browser for SQLite.
I have developed a mobile application using the CodeName One plugin for Java in the Netbeans IDE.
CodeName One uses the Database API. https://www.codenameone.com/javadoc/com/codename1/db/Database.html
I'm running some tests (there are around 10 values I would like to upload, however, just testing the connection ect by uploading ID, Fname and Lname values.
Database db = null;
Cursor cur = null;
String Fname = findTxtFirstn(c).getText();
String Lname = findTxtLastn(c).getText();
try{
Database ARdb = Display.getInstance().openOrCreate("RecordsDB.db");
System.out.println("Connection secured to database.");
ARdb.beginTransaction();
String createTable = "CREATE TABLE IF NOT EXISTS RecordsTable ("
+ "ID integer PRIMARY KEY,"
+ "First_Name text NOT NULL,"
+ "Last_Name text NOT NULL)";
String query = "insert into RecordsTable (ID,First_Name,Last_Name) values (3,'Test','Testerton')";
ARdb.execute(createTable);
ARdb.execute(query);
ARdb.commitTransaction();
} catch(Exception e){
System.out.println("Error! Connection Failed to DB" +e.getMessage());
} finally {
Util.cleanup (db);
Util.cleanup(cur);
}
I get no errors and everything runs, however, the values are not in the database when I check it. Am I missing something here? I have followed tutorials and looked over the Codename One API. I can't find the solution.
Edit: I need to change the value of the primary number each run (else I get an error: number needs to be unique), This tells me the values are being stored on the database, unfortunately, when I check the database in question there are no records on it, so where it the data going?
I used DB Browser for SQLite.
Have you tried performing your modifying change in a transaction? In databases with transactions all modifying operations (CREATE, INSERT, ...) need to be performed in a transaction.
ARdb.beginTransaction();
// your create code
ARdb.commitTransaction();
It appears that SQLite does not enforce foreign keys by default. I'm using sqlitejdbc-v056.jar and I've read that using PRAGMA foreign_keys = ON; will turn on foreign key constraints, and that this needs to be turned on in a per-connection basis.
My question is: what Java statements do I need to execute to turn on this command? I've tried:
connection.createStatement().execute("PRAGMA foreign_keys = ON");
and
Properties properties = new Properties();
properties.setProperty("PRAGMA foreign_keys", "ON");
connection = DriverManager.getConnection("jdbc:sqlite:test.db", properties);
and
connection = DriverManager.getConnection("jdbc:sqlite:test.db;foreign keys=true;");
but none of those work. Is there something I am missing here?
I've seen this answer and I want to do exactly the same thing, only using JDBC.
Code like this:
DriverManager.getConnection("jdbc:sqlite:some.db;foreign keys=true;")
Does not work.
You have to create org.sqlite.SQLiteConfig and set it as properties when call getConnection from DriverManager.
public static final String DB_URL = "jdbc:sqlite:database.db";
public static final String DRIVER = "org.sqlite.JDBC";
public static Connection getConnection() throws ClassNotFoundException {
Class.forName(DRIVER);
Connection connection = null;
try {
SQLiteConfig config = new SQLiteConfig();
config.enforceForeignKeys(true);
connection = DriverManager.getConnection(DB_URL,config.toProperties());
} catch (SQLException ex) {}
return connection;
}
This code taken from this.
When you look at the SQLite Foreign Key Support page I would interpret that
SQLlite has to be compiled with foreign key support
You still have to turn it on for each connection with PRAGMA
You have to define the foreign key as constraint when you create the table
Ad 1) Quoted from here:
If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined).
What is your result for PRAGMA foreign_keys;?
Update: from your comment I see you are using 3.6.14.2, this means your version is not supporting foreign key constraints! So you have to update SQLite, if this is possible!
Ad 2) Your first code snippet executes the PRAGMA as statement, I don't think this will work. The third snipped didn't work based on your comment: the SQLite driver interprets the whole string as the location of the database, instead of taking the "foreign keys=true" part as connection settings". So only the second snippet will work.
Ad 3) Did you create the table with foreign key support? Quoted from here:
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
this page was helpful when translating to Clojure, however my solution was different. So, for posterity, even though the OP asked for Java, this is how I did it in Clojure:
(def db-spec {:connection-uri "jdbc:sqlite:db.sqlite3?foreign_keys=on;"})
I unfortunately can't comment on the previous poster's answer but as a heads up for anybody else who may come by here, the first code snippet:
connection.createStatement().execute("PRAGMA foreign_keys = ON");
absolutely does work when your version of SQLite is up to date and supports foreign key support.
Try
connection = DriverManager.getConnection("jdbc:sqlite:test.db;foreign keys=true;");
Based on the question you linked, it looks to be a likely candidate.
On a linux desktop, when I tried,
connection = DriverManager.getConnection("jdbc:sqlite:/path/to/test.db;foreign keys=true;");
sqlite3 (3.7.13) thought that my database file was /path/to/test.db;foreign keys=true. This led to the strange, but I guess appropriate, error: table does not exist
See how to solve no such table while inserting exception in sqlite data base
I thought I had fixed both of these issues by stuffing the foreign key statement into a property like so:
private final Properties connectionProperties = new Properties();
connectionProperties.setProperty("PRAGMA foreign_keys", "ON");
private final String connectionString = String.format("jdbc:sqlite:%s", absolute_path_to_sqlite_db);
Connection connection = DriverManager.getConnection(connectionString, connectionProperties);
But even tho the database name issue was resolved, SQLite was still allowing constraint violations. Some more noodling with Xerial's driver and this is what finally worked:
private final Properties connectionProperties = new Properties();
SQLiteConfig config = new SQLiteConfig();
config.enforceForeignKeys(true);
connectionProperties = config.toProperties();
private final String connectionString = String.format("jdbc:sqlite:%s", absolute_path_to_sqlite_db);
Connection connection = DriverManager.getConnection(connectionString, connectionProperties);
I use mybatis, in mybatis-config.xml :
<property name="url" value="jdbc:sqlite:example.db?foreign_keys=on;"/>
that's work for mybatis framework.
I found this question while Googling the same problem. I was using sqlitejdbc-v056.jar from Zentus, which uses an older version of the SQLite driver, and doesn't support foreign keys.
I tried what seems to be the Xerial driver v3.7.2 from the Maven Repository
I have not researched the difference between these drivers, but a hot-switch between the two didn't break anything and fixed my issue, so, I hope this helps someone.
I am getting below exception, when trying to insert a batch of rows to an existing table
ORA-00942: table or view does not exist
I can confirm that the table exists in db and I can insert data to that table using oracle
sql developer. But when I try to insert rows using preparedstatement in java, its throwing table does not exist error.
Please find the stack trace of error below
java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1889)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout>>(OracleStatement.java:2709)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at quotecopy.DbConnection.insertIntoDestinationDb(DbConnection.java:591)
at quotecopy.QuoteCopier.main(QuoteCopier.java:72)
Can anyone suggest the reasons for this error ?
Update : Issue solved
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
Why an error table or view does exist error was throws for error in inserting clob data. Could anyone of you please explain ?
Thanks a lot for your answers and comments.
Oracle will also report this error if the table exists, but you don't have any privileges on it. So if you are sure that the table is there, check the grants.
There seems to be some issue with setCLOB() that causes an ORA-00942 under some circumstances when the target table does exist and is correctly privileged. I'm having this exact issue now, I can make the ORA-00942 go away by simply not binding the CLOB into the same table.
I've tried setClob() with a java.sql.Clob and setCLOB() with an oracle.jdbc.CLOB but with the same result.
As you say, if you bind as a string the problem goes away - but this then limits your data size to 4k.
From testing it seems to be triggered when a transaction is open on the session prior to binding the CLOB. I'll feed back when I've solved this...checking Oracle support.
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
#unbeli is right. Not having appropriate grants on a table will result in this error. For what it's worth, I recently experienced this. I was experiencing the exact problem that you described, I could execute insert statements through sql developer but would fail when using hibernate. I finally realized that my code was doing more than the obvious insert. Inserting into other tables that did not have appropriate grants. Adjusting grant privileges solved this for me.
Note: Don't have reputation to comment, otherwise this may have been a comment.
We experienced this issue on a BLOB column. Just in case anyone else lands on this question when encountering this error, here is how we resolved the issue:
We started out with this:
preparedStatement.setBlob(parameterIndex, resultSet.getBlob(columnName)); break;
We resolved the issue by changing that line to this:
java.sql.Blob blob = resultSet.getBlob(columnName);
if (blob != null) {
java.io.InputStream blobData = blob.getBinaryStream();
preparedStatement.setBinaryStream(parameterIndex, blobData);
} else {
preparedStatement.setBinaryStream(parameterIndex, null);
}
I found how to solve this problem without using JDBC's setString() method which limits the data to 4K.
What you need to do is to use preparedStatement.setClob(int parameterIndex, Reader reader). At least this is what that worked for me. Thought Oracle drivers converts data to character stream to insert, seems like not. Or something specific causing an error.
Using a characterStream seems to work for me. I am reading tables from one db and writing to another one using jdbc. And i was getting table not found error just like it is mentioned above. So this is how i solved the problem:
case Types.CLOB: //Using a switch statement for all columns, this is for CLOB columns
Clob clobData = resultSet.getClob(columnIndex); // The source db
if (clobData != null) {
preparedStatement.setClob(columnIndex, clobData.getCharacterStream());
} else {
preparedStatement.setClob(columnIndex, clobData);
}
clobData = null;
return;
All good now.
Is your script providing the schema name, or do you rely on the user logged into the database to select the default schema?
It might be that you do not name the schema and that you perform your batch with a system user instead of the schema user resulting in the wrong execution context for a script that would work fine if executed by the user that has the target schema set as default schema. Your best action would be to include the schema name in the insert statements:
INSERT INTO myschema.mytable (mycolums) VALUES ('myvalue')
update: Do you try to bind the table name as bound value in your prepared statement? That won't work.
It works for me:
Clob clob1;
while (rs.next()) {
rs.setString(1, rs.getString("FIELD_1"));
clob1 = rs.getClob("CLOB1");
if (clob1 != null) {
sta.setClob(2, clob1.getCharacterStream());
} else {
sta.setClob(2, clob1);
}
clob1 = null;
sta.setString(3, rs.getString("FIELD_3"));
}
Is it possible that you are doing INSERT for VARCHAR but doing an INSERT then an UPDATE for CLOB?
If so, you'll need to grant UPDATE permissions to the table in addition to INSERT.
See https://stackoverflow.com/a/64352414/1089967
Here I got the solution for the question. The problem is on glass fish if you are using it. When you create JNDI name make sure pool name is correct and pool name is the name of connection pool name that you are created.