Creating an in-memory Database and Table if not exist - sqlite

I am trying to create an in-memory DB using sqllite
Connection inMemConn = null;
Class.forName("org.sqlite.JDBC");
inMemConn = DriverManager.getConnection("jdbc:sqlite:inMemDB.db");
Statement DBCreateTable = inMemConn.createStatement();
DBCreateTable.executeUpdate("CREATE DATABASE IF NOT EXISTS inMemDB" );
DBCreateTable.executeUpdate("USE inMemDB");
DBCreateTable. executeUpdate("CREATE TABLE IF NOT EXISTS pNumbertable");
and i am trying to populate it with some Java Objects
final String DBinsert = "INSERT INTO pNumbertable VALUES(?,?)";
PreparedStatement DBAddObjects = inMemConn.prepareStatement(DBinsert);
for (int i = 0; i < List.size(); i++) {
for (int j = 0; j < List2.size(); j++) {
DBAddObjects.setObject(1, XList.get(i)[0]);
DBAddObjects.setObject(2, YList.get(j)[1]);
DBAddObjects.executeUpdate();
}
}
DBAddObjects.close();
inMemConn.close();
But, while running the code, I get the following error.
near "DATABASE": syntax error
Also, is it the correct way to create an in-mem DB.?

There is on CREATE DATABASE statement in SQLite; databases are created by creating a connection with the desired file name.
You have opened (or created) a database with the file name inMemDB.db.
To create an in-memory database, you must use the special file name :memory: instead:
DriverManager.getConnection("jdbc:sqlite::memory:");

Related

Duplicate entry unique key.... my error catching failed

So I am updating something but I only want it to make a record for new records.
for (var i=0; i<allquery.length;i++)
{
var oldrecord = allquery[i];
var newrecord = app.models.xx.newRecord();
newrecord.gPor = xxString;
newrecord.UniqueNumber = oldrecord.Unique;
newrecord.Name = oldrecord.dname;
try{app.saveRecords([newrecord]);//this is line 30
results.push(newrecord);}catch(e){Logger.log (e+ " "+oldrecord.dname);}
}//for loop
I'm frustrated because the sql error should be caught in the try catch (it is appearing for the saveRecords line... but instead it is killing the script. Thoughts? do I need to implement manual save mode? (which will require rewriting elsewhere.
The error is:
Exception: Malformed SQL. More information: Error with SQL statement:
Duplicate entry '0270' for key 'UniqueNumber_unique'. at
createApprovals (ApprovalBugScripts:30)
Enclosing the entire creation part in a try catch worked:
for (var i=0; i<allquery.length;i++)
{
try{
var oldrecord = allquery[i];
var newrecord = app.models.xx.newRecord();
newrecord.gPor = xxString;
newrecord.UniqueNumber = oldrecord.Unique;
newrecord.Name = oldrecord.dname;
app.saveRecords([newrecord]);//this is line 30
results.push(newrecord);}catch(e){Logger.log (e+ " "+oldrecord.dname);}
}//for loop

sqlite commands possibly not working in qt

I am making a library management software using Qt and Sqlite3.
constructor:
db = QSqlDatabase :: addDatabase("QSQLITE");
model = new QSqlTableModel(this, db);
db.setDatabaseName(":/lib/libre coupe.db");
db.setHostName("Libre Coupe");
if(db.open())
{
QSqlQuery query(db);
if (! query.exec("CREATE TABLE IF NOT EXISTS books (NAME VARCHAR(100) NOT NULL, AUTHOR VARCHAR(100) NOT NULL, UID VARCHAR(100) NOT NULL) "))
{
QMessageBox::information(this, "title", "Unable to use Sqlite");
}
if(query.lastError().text() != " ")
QMessageBox::critical(this, "Oops", query.lastError().text());
model->setTable("books");
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("Name") );
model->setHeaderData(1, Qt::Horizontal, tr("Author") );
model->setHeaderData(2, Qt::Horizontal, tr("Uid") );
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
if(!query.exec("SELECT * FROM books;"))
QMessageBox::critical(this, "Oops", query.lastError().text());
int i = 0;
while(query.next())
{
model->setData(model->index(i, 0), query.value(query.record().indexOf("NAME")));
model->setData(model->index(i, 1), query.value(query.record().indexOf("AUTHOR")));
model->setData(model->index(i, 2), query.value(query.record().indexOf("UID")));
++i;
}
}
else
QMessageBox::critical(this, "Oops!", "Could not open the database");\
I faced a problem that the database was not created automatically. So, i created it manually and added it to my resource so that it exists on every computer which uses my application.
I ran my app and went to the directory containing "libre coupe.db". There using the terminal, i found out that no table was created. I see no error message. My other functions like save don't work too while the same commands typed directly into Sqlite using terminal works as expected.
I even used the debugger and found that the program does enter the if condition i.e. the database opens successfully.
I used the following command to check if the table existed:
sqlite3 "libre coupe.db"
.tables
First line:
db.setDatabaseName(":/lib/libre coupe.db");
the starting ":" means you are trying to access an embedded binary resource using Qt's resource system.
However, SQLite databases cannot be stored in the Qt resource system. If your database is instead located at /lib/libre coupe.db, you should remove the colon at the beginning.

Batch Insert using a loop to add to table storage in windows azure

I am trying to do a batch insert from a list of objects to table storage in Windows Azure.
I am using the storage emulator for now.
I get this error:
"Unexpected response code for operation".
I tried to search for anyone who encountered similar problems but to no avail.
My keys are setup this way:
PartitionKey = "projects" + CompanyID.toString();
RowKey = ProjectID.toString();
It is inserted like this:
foreach (vProject item in projectList)
{
TableOperation retrieveOperation = TableOperation.Retrieve<mMultipleSave.ViewProjectEntity>("projects" + CompanyID.toString(), item.ProjectID.ToString());
TableResult retrievedResult = table.Execute(retrieveOperation);
if (retrievedResult.Result != null)
{
mMultipleSave.ViewProjectEntity updateEntity = (mMultipleSave.ViewProjectEntity)retrievedResult.Result;
if (!item.isProjectArchived)
{
//update entity in table storage
updateEntity.ProjectClient = item.ClientName;
updateEntity.ProjectCompany = item.Company;
updateEntity.ProjectName = item.ProjectName;
batchUpdateOperation.Replace(updateEntity);
}
else {
//delete project in table storage if it is archived in the database
batchDeleteOperation.Delete(updateEntity);
}
}
else //if it does not exist in table storage insert
{
mMultipleSave.ViewProjectEntity entity = new mMultipleSave.ViewProjectEntity(CompanyID, item.ProjectID);
entity.ProjectClient = item.ClientName;
entity.ProjectCompany = item.Company;
entity.ProjectName = item.ProjectName;
batchInsertOperation.Insert(entity);
}
}
if (batchInsertOperation.Count > 0)
table.ExecuteBatch(batchInsertOperation);
if (batchUpdateOperation.Count > 0)
table.ExecuteBatch(batchUpdateOperation);
if (batchDeleteOperation.Count > 0)
table.ExecuteBatch(batchDeleteOperation);
It gets an error on table.ExecuteBatch(batchInsertOperation);
Please help.
I have solved the problem. Update your windows azure tools including the emulator to the latest version. As of today, it is in version 2.0

Retrieve Cellset Value in SSAS\MDX

Im writing SSAS MDX queries involving more than 2 axis' to retrieve a value. Using ADOMD.NET, I can get the returned cellset and determine the value by using
lblTotalGrossSales.Text = CellSet.Cells(0).Value
Is there a way I can get the CellSet's Cell(0) Value in my MDX query, instead of relying on the data returning to ADOMD.NET?
thanks!
Edit 1: - Based on Daryl's comment, here's some elaboration on what Im doing. My current query is using several axis', which is:
SELECT {[Term Date].[Date Calcs].[MTD]} ON 0,
{[Sale Date].[YQMD].[DAY].&[20121115]} ON 1,
{[Customer].[ID].[All].[A612Q4-35]} ON 2,
{[Measures].[Loss]} ON 3
FROM OUR_CUBE
If I run that query in Management Studio, I am told Results cannot be displayed for cellsets with more than two axes - which makes sense since.. you know.. there's more than 2 axes. However, if I use ADOMD.NET to run this query in-line, and read the returning value into an ADOMD.NET cellset, I can check the value at cell "0", giving me my value... which as I understand it (im a total noob at cubes) is the value sitting where all these values intersect.
So to answer your question Daryl, what I'd love to have is the ability to have the value here returned to me, not have to read in a cell set into the calling application. Why you may ask? Well.. ultimately I'd love to have one query that performs several multi-axis queries to return the values. Again.. Im VERY new to cubes and MDX, so it's possible Im going at this all wrong (Im a .NET developer by trade).
Simplify your query to return two axis;
SELECT {[Measures].[Loss]} ON 0, {[Term Date].[Date Calcs].[MTD] * [Sale Date].[YQMD].[DAY].&[20121115] * [Customer].[ID].[All].[A612Q4-35]} ON 1 FROM OUR_CUBE
and then try the following to access the cellset;
string connectionString = "Data Source=localhost;Catalog=AdventureWorksDW2012";
//Create a new string builder to store the results
System.Text.StringBuilder result = new System.Text.StringBuilder();
AdomdConnection conn = new AdomdConnection(connectionString);
//Connect to the local serverusing (AdomdConnection conn = new AdomdConnection("Data Source=localhost;"))
{
conn.Open();
//Create a command, using this connection
AdomdCommand cmd = conn.CreateCommand();
cmd.CommandText = #"SELECT { [Measures].[Unit Price] } ON COLUMNS , {[Product].[Color].[Color].MEMBERS-[Product].[Color].[]} * [Product].[Model Name].[Model Name]ON ROWS FROM [Adventure Works] ;";
//Execute the query, returning a cellset
CellSet cs = cmd.ExecuteCellSet();
//Output the column captions from the first axis//Note that this procedure assumes a single member exists per column.
result.Append("\t\t\t");
TupleCollection tuplesOnColumns = cs.Axes[0].Set.Tuples;
foreach (Microsoft.AnalysisServices.AdomdClient.Tuple column in tuplesOnColumns)
{
result.Append(column.Members[0].Caption + "\t");
}
result.AppendLine();
//Output the row captions from the second axis and cell data//Note that this procedure assumes a two-dimensional cellset
TupleCollection tuplesOnRows = cs.Axes[1].Set.Tuples;
for (int row = 0; row < tuplesOnRows.Count; row++)
{
for (int members = 0; members < tuplesOnRows[row].Members.Count; members++ )
{
result.Append(tuplesOnRows[row].Members[members].Caption + "\t");
}
for (int col = 0; col < tuplesOnColumns.Count; col++)
{
result.Append(cs.Cells[col, row].FormattedValue + "\t");
}
result.AppendLine();
}
conn.Close();
TextBox1.Text = result.ToString();
} // using connection
Source : Retrieving Data Using the CellSet
This is fine upto select on columns and on Rows. It will be helpful analyze how to traverse sub select queries from main query.

C# - Insert Multiple Records at once to AS400

I have a problem like this:
1. I retrieve data from MySQL using C# ASP .Net. -- done --
2. All data from no.1 will be inserted into table on AS400. -- I got an error on this step --
Error message says that ERROR [42000] [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0104 - Token ; was not valid. Valid tokens: <END-OF-STATEMENT>.. It's true that I used semicolon to separate queries with each others, but it's not allowed. I've Googling but I can't find the solution.
My question is what the <END-OF-STATEMENT> means of that error message..?
Here is my source code.
private static void doInsertDOCADM(MySqlConnection conn)
{
// Get Temporary table
String query = "SELECT * FROM TB_T_DOC_TEMPORARY_ADM";
DataTable dt = CSTDDBUtil.ExecuteQuery(query);
OdbcConnection as400Con = null;
as400Con = CSTDDBUtil.GetAS400Connection();
as400Con.Open();
if (dt != null && dt.Rows.Count > 0)
{
int counter = 1, maxInsertLoop = 50;
using (OdbcCommand cmd = new OdbcCommand())
{
cmd.Connection = as400Con;
foreach (DataRow dr in dt.Rows)
{
cmd.CommandText += "INSERT INTO DCDLIB.WDFDOCQ VALUES " + "(?,?,?,?);";
cmd.Parameters.Add("1", OdbcType.VarChar).Value = dr["PROD_MONTH"].ToString();
cmd.Parameters.Add("2", OdbcType.VarChar).Value = dr["NEW_MAIN_DEALER_CD"].ToString();
cmd.Parameters.Add("3", OdbcType.VarChar).Value = dr["MODEL_SERIES"].ToString();
cmd.Parameters.Add("4", OdbcType.VarChar).Value = dr["MODEL_CD"].ToString();
if (counter < maxInsertLoop)
{
counter++;
}
else
{
counter = 1;
cmd.ExecuteNonQuery();
cmd.CommandText = "";
cmd.Parameters.Clear();
}
}
if (counter > 1) cmd.ExecuteNonQuery();
}
}
Notes: I used this way (Collect some queries first, and then execute those query) to improve the performance of my application.
As Clockwork-Muse pointed out, the problem is that you can only run a single SQL statement in a command. The iSeries server does not handle multiple statements at once.
If your iSeries server is running V6R1 or later, you can use block inserts to insert multiple rows. I'm not sure if you can do so through the ODBC driver, but since you have Client Access, you should be able to install the iSeries ADO.NET driver. There are not many differences between the ADO.NET iSeries driver and the ODBC one, but with ADO.NET you get access to iSeries specific functions.
With the ADO.NET driver, multiple insert become a simple matter of :
using (iDB2Connection connection = new iDB2Connection(".... connection string ..."))
{
// Create a new SQL command
iDB2Command command =
new iDB2Command("INSERT INTO MYLIB.MYTABLE VALUES(#COL_1, #COL_2", connection);
// Initialize the parameters collection
command.DeriveParameters();
// Insert 10 rows of data at once
for (int i = 0; i < 20; i++)
{
// Here, you set your parameters for a single row
command.Parameters["#COL_1"].Value = i;
command.Parameters["#COL_2"].Value = i + 1;
// AddBatch() tells the command you're done preparing a row
command.AddBatch();
}
// The query gets executed
command.ExecuteNonQuery();
}
}
There is also some reference code provided by IBM to do block inserts using VB6 and ODBC, but I'm not sure it can be easily ported to .NET : http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Frzaik%2Frzaikextfetch.htm
Hope that helps.
When it says <END-OF-STATEMENT> it means about what it says - it wants that to be the end of the executed statement. I don't recall if the AS/400 allows multiple statements per execution unit (at all), but clearly it's not working here. And the driver isn't dealing with it either.
Actually, you have a larger, more fundamental problem; specifically, you're INSERTing a row at a time (usually known as row-by-agonizing-row). DB2 allows a comma-separated list of rows in a VALUES clause (so, INSERT INTO <table_name> VALUES(<row_1_columns>), (<row_2_columns>)) - does the driver you're using allow you to provide arrays (either of the entire row, or per-column)? Otherwise, look into using extract/load utilities for stuff like this - I can guarantee you that this will speed up the process.

Resources