I'm attempting to add a few reports to my Android app. First, I defined them as Views in my SQLite database to make sure they work correctly. Here's one of them:
CREATE VIEW r3_DNFs AS SELECT Epreuve, Dossard, STRFTIME('%H:%M:%S %d',TempsPassage) AS "Temps" FROM Coureurs WHERE Statut is "DNF" ORDER BY SUBSTR(Epreuve, 5) + 0 DESC, Dossard;
Can I use the following to simplify my coding?
Cursor c = db.rawQuery("SELECT Epreuve, Dossard, Temps FROM r3_DNFs",null);
With rawQuery you can use any valid sqlite's statement but it should not be terminated (which doesn't contain the ; symbol).
Related
I am trying to setup a query for my application to pull only values from a table that have a specific column set. Mostly this column will be null, but if you edit and save the item on the application end without putting anything in this field, then it saves a blank string to that database field.
I have tried the TSQL query:
SELECT * from TABLE where COLUMN is not NULL AND COLUMN != ''
This query returns the results I need, but when I run the same query in HQL:
SELECT OBJECT from TABLE where COLUMN is not NULL and COLUMN <> ''
Then it still contains the values that have a blank string in that column. I have tried this using HQL with the operators <> and !=, and have also tried converting it to a criteria object using Restrictions.ne("column","") but nothing seems to provide the result I need.
I tried Length as in the comments, but had no luck. With the length in the query hibernate generates the full query as so. the time_clock_id column is the one that i'm having the problem with. Hibernate is set to SQLServerDialect
select timezone0_.time_zone_id as time1_368_, timezone0_.version as version368_, timezone0_.modification_timestamp as modifica3_368_, timezone0_.time_offset as time4_368_, timezone0_.modification_user as modifica5_368_, timezone0_.name as name368_, timezone0_.description as descript7_368_, timezone0_.active as active368_, timezone0_.time_clock_id as time9_368_ from time_zone timezone0_ where timezone0_.active=1 and (timezone0_.time_clock_id is not null) and len(timezone0_.time_clock_id)>0
Rookie Mistake. There was another place within my action class where I was using a different query to build the select list in the application. This was resulting in the list being overwritten with all values instead of those that use blank. After snipping this duplication I can use the operator column <> '' and I am getting the correct results
I have a database view which selects two columns from two different tables with the same name.
For example generating a DDL for the view would generate the following:
create view MYSCHEMA.VPRODUCTS ("Name", "AlternameName"...) AS
A.Name,
B.Name,
from PRODUCTSA A
left join PRODUCTSB B
...
When I run the command to generate a Liquibase change set, the SQL in the tag only contains a select statement for the two columns and makes no distinction for the unique column name (i.e. "Name", "AlternameName").
<createView viewName="VPRODUCTS ">SELECT
A.Name
,B.Name
from PRODUCTSA A
left join PRODUCTSB B
...
As a result, whenever I try to execute the change set Liquibase complains about duplicate entries for columns with the same name.
I can fix this by adding SQL "AS" statements in the tag, but I'd prefer if there was a better way to do this.
<createView viewName="VPRODUCTS ">SELECT
A.Name
,B.Name AS AlternateName
from PRODUCTSA A
left join PRODUCTSB B
...
Is there an attribute or tag that would allow me to specify the column names when creating the view, or providing the raw SQL in the DDL?
There isn't another way. Liquibase simply passes the nested SELECT statement into the create view statement so whatever is required in the select needs to be part of the query. There is no built-in pre-processing of the view statement beyond pre-pending "CREATE VIEW X"
If you want to provide the raw SQL you can always use the tag.
Another way would be to use subselects, like this:
SELECT [COLUMNLIST 1:1 RENAMED] FROM (your view)
Or use WITH blocks along the same line of thinking.
So I've been reading the Android Developer docs and have spent the last few hours reading tutorials online and have downloaded a few samples. Some of them compile, some don't.
The ones that compile use the SQLLiteDatabase in different ways than other samples I downloaded. I'm now totally confused. I was following along with the Training docs on http://developer.android.com/guide/topics/data/data-storage.html#db until I got half way down the page where it just stopped, and said that we can checkout the Note Pad sample. But the Notepad sample uses different code than what I had just read in the docs.
My scenario:
Display ListView that pulls data from SQLiteDatabase in MainActivity.xml
If user presses 'Add entry' button in AddEntryActivity.xml, add the entry to the database
If user presses 'Delete entry' button in DeleteEntryActivity.xml, delete the entry in the database.
So it's pretty simple stuff which I could do in just a couple minutes in C# but I'm new to android and I have absolutely no idea where to start. I started with the documentation, but all it does it go about half way and then refers you to the sample which is just more confusing since it uses different code.
How can I achieve this?
Use SQLiteDatabase class for this
SQLiteDatabase db = openOrCreateDatabase("Database_Name", MODE_PRIVATE, null);
//Create Table
String strsql = "CREATE TABLE IF NOT EXISTS TableName(Name VARCHAR(30),id INT(15) unique) ";
db.execSQL(strsql);
you can fire query as you do in MYSQL(INSERT,UPDATE,DELETE) using db.execSQL()
To Retrive data you can use this
strsql = "SELECT * FROM TableName ";
Cursor c = db.rawQuery(strsql, null);
int count = c.getCount();
c.moveToFirst();
while (k >= 0) {
ListviewContent.add(c.getString(c.getColumnIndex("Name")));
setListAdapter(new ListViewAdapter(this));
c.moveToNext();
k--;
}
//you can set retrived data to list view as shown above.
I'm trying to run use rawquery to run a query with an alias on the primary key to make it _id so that I can use the SimpleCursorAdapter, this is what I have:
String sel = DatabaseListDB.COLUMN_DATABASE_NAME;
Cursor results = db.rawQuery("SELECT ? as _id FROM DatabaseList",
new String[] {sel});
In my SqlLiteHelperClass
public static final String COLUMN_DATABASE_NAME = "databaseName";
is the column name I want and my primary key. The problem is when I run this query the results come up with 'databaseName' as the values in the table instead of the actual values.
I can run the query as
Cursor results = db.rawQuery("SELECT databaseName as _id FROM DatabaseList",
null);
and it works fine and I have no idea why I cant use the selectionargs properly. Can anyone help me fix this?
? is supposed to use for WHERE arguments. In your case, you should simply alter your query as:
Cursor results = db.rawQuery(String.format("SELECT %s as _id FROM DatabaseList", sel));
From developer.android.com, you only can put "?" on where clause, not for columns you want to query:
selectionArgs: You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.
I am trying to build a dynamic sql query in java (shown below)
sqlStr = "Select * " +
"from " + tableName
if(tableName!=null){
if(tableName.equals("Table1"){
sqlStr = sqlStr.concat("order by city desc");
}else if(tableName.equals("Table2"){
sqlStr = sqlStr.concat("order by country desc");
}else if(tableName.equals("Table3"){
sqlStr = sqlStr.concat("order by price desc");
}
}
Now what i would like to do is to add a final 'else' statement which would order the query based on whether the table contains a column named 'custID'. There will be several tables with that column so i want to sort the ones that have that column by custID. (Rather than having hundreds of additional if statements for each table that does have that column name.) Is this possible? i have seen people using the 'decode' function but i cant work out how to use it here.
Use DatabaseMetaData to get the table information.
You can use the getTablexxx() and getColumnxx() methods to get the table information.
Connection conn = DriverManager.getConnection(.....);
DatabaseMetaData dbmd = conn.getMetaData();
dbmd.getxxxx();
Note: you forgot space in your code before ORDER BY clause.
If you are happy with hardcoding things, a way to avoid multiple conditionals would be to store a list of all the tables that include custID.
private final static String tablesWithCustID = "/TableX/TableY/TableZ/";
...
if (tablesWithCustID.contains( tableName )) {
sqlStr = sqlStr.concat("order by custID")
}
You could use a List instead of a simple delimited string if you like.
Perhaps better, you could store a map with table names as the key, and the sort string as the value. Load it up once, then you don't need any conditional at all.
The most straight-forward way to do it is to read the column definitions from USER_TAB_COLUMNS or ALL_TAB_COLUMNS and check for the existence of a custID column. Without crazy PL/SQL tricks, you won't be able to solve this in SQL alone.
BTW, there is a " " missing between tableName and the order by clauses.
I understand that you're looking for a solution that can do this in one query, i.e. without running a separate metadata query beforehand.
Unfortunately, this won't be possible. The decode function can do some dynamic things with column values, but not with column name. And you're looking for a solution dynamically derive the column name.
An alternative might be to just add ORDER BY 1, 2. This is an old syntax that means order by the first and than by the second column. It might be a good solution if the custID column is the first column. Otherwise it at least gives you some sorting.
How about ArrayList.contains()?
You can create a list of tables which have that column, and just check for tables.contains(tablename) in the final if condition.