var which = {};
which['creditcards'] = "tx.executeSql('SELECT * FROM " + table + " ', [], querySucess, errorCB)";
db.transaction(function(tx){
which[table];
});
I want to be able to dynamically insert the select statement based on the variable clicked. Is this possible? Am I going about it the right way?
Yes it's possible but no, you don't appear to be going about it the right way - I'd expect something more like the following:
function dbQueryWrapper(table) { // table is a string supplied from onclick etc
db.transaction (
function(tx) {
tx.executeSql(
'SELECT * FROM ?;', [ table ], querySucess, errorCB
);
}
);
}
The second param with the [] is an array of stuff you want to pass into your query - each item fills on ? in the query
Related
I have situation where I need to write a sql select query which is technically need to be repeated to all the items in a list.
For example, say I have list like this,
list =[ { item_1: value_11,
item_2: value_12,
item_3: value_13,
item_4: value_14'
},
{ item_1: value_21,
item_2: value_22,
item_3: value_23,
item_4: value_24,
},
{ item_1: value_31,
item_2: value_32,
item_3: value_33,
item_4: value_34,
},
......
];
Now I need to write a SELECT query to get all the related records for each of the item, something like,
//for each item
SELECT * FROM tbl WHERE tbl.fld1 = list[0].item_1 AND tbl.fld2 = list[0].item_2 AND tbl.fld3 = list[0].item_3 AND tbl.fld4 = list[0].item_4;
Is it possible to write a single query for the same within SQL statement (kind of loop) or else does it need to be repeated from the coding side so it will call the db for each items separately.
Please help,
Thank You in advance
As #draz already commented you need to loop over the list to dynamically create the sql statement. You can loop over it in your code and generate a single sql statement that can be send to the database once.
A simple but probably not the nicest idea would be something like:
sql_select = "SELECT * FROM tbl WHERE";
first_item = true;
for (element in list) {
sql_select = (first_item) ? sql_select : sql_select + " OR";
fist_item = false;
where_clause = ` (tbl.fld1 = ${element.item_1} AND tbl.fld2 = ${element.item_2} AND tbl.fld3 = ${element.item_3} AND tbl.fld4 = ${element.item_4})`;
sql_select.concat(where_clause);
}
I have a JSON like this:
{"name":[{"tag":"Peter"}]}
And I'm dynamically building a prepared statement with multiple wildcards like this:
var sqlVar;
sqlVar += existParams.map(field => {
if (field === 'name') {
function getValues(item, index) {
var getVal = [item.tag];
return `${field} LIKE ?`;
}
return '('+name.map(getValues).join(' OR ')+')';
} else {
return `(${field} = ?)`
}
}).join(" AND ");
var sql = "SELECT * FROM names "+sqlVar+"";
connection.query(sql,
...
function getValues(item, index) {
var getVal = [item.tag];
return '%' + getVal + '%';
}
return name.map(getValues);
//Further attempts
//var getResult = name.map(getValues);
//return getResult.split(",");
//return name.map(getValues).join(', ');
, function(err, rows) {
...
});
If I have one value it works just fine. In console.log (SQL) I can see:
SELECT * FROM names WHERE (name LIKE ?)
BUT... if I have multiple values like:
{"name":[{"tag":"Peter"},{"tag":"Jack"}]}
I'm getting an SQL Error:
sql: 'SELECT * FROM names WHERE (name LIKE \'%Peter%\', \'%Jack%\' OR name LIKE ?) }
... So the second value is not going to the second position.
... but the result should be:
sql: 'SELECT * FROM names WHERE (name LIKE \'%Jack%\' OR name LIKE \'%Peter%\') }
... so in the console.log(sql):
SELECT * FROM names WHERE (name LIKE ? OR name LIKE ?)
What am I missing and how can I get the second value to the second LIKE and so on?!
Here is a similar example but with only one value: nodejs throws error with mysql like query via prepared statements
The only reason here for the resulting statement to be 'SELECT * FROM names WHERE (name LIKE \'%Peter%\', \'%Jack%\' OR name LIKE ?)
is that you have passed a nested array with value [['%Peter%', '%Jack%']] instead of a flat one.
Using the given object say,
const source = {"name":[{"tag":"Peter"}, {"tag":"Jack"}]}
Then the query values for the prepared statement should be
const queryValues = source.name.map(({tag}) => `%${tag}%`);
// [ '%Peter%', '%Jack%' ]
connect.query(sql, queryValues, (err, rows) => {
});
I have objects in Parse called "Post" and within that, I have columns called "title" and "content". I am trying to ask the user for an input value and save this as "remove". If the user's input value ("remove") matches a "title" value already saved in parse.com, I want to delete the entire row in parse, so that both the "title", "content" and everything else in the row is deleted. The deleting part is not working so I am wondering if my code is actually making it go through all the data saved in parse and find the one that matches the user's input and then delete it.
What am I doing incorrectly and what can I change to make it delete the entire row?
Thank you in advance.
function getPosts(){
var query = new Parse.Query(Post);
query.find({
success: function(results){
for(var i in results){
var title = results[i].get("title");
var content = results[i].get("content");
var remove = $("#post-remove").val();
console.log("Remove: "+remove);
console.log("MAC Address: " +title);
console.log("place: "+content);
if (title == remove)
{
window.alert("The MAC address matches.");
console.log(remove+" matches " + title+ " and is located in " +content);
var Post = Parse.Object.extend("Post");
var query = new Parse.Query(Post);
query.find("objectId", {
success: function(yourObj){
//console.log(yourObj);
//Post.destroy({}); //if title matches remove, delete the Post (title and content) (but it's not deleting it)
Post.remove("title");
Post.remove("content");
}
});
}
}
}
});
}
To clarify and add a bit to #JakeT's acceptable answer:
1) find objects to delete like this:
function postsMatching(title) {
var Post = Parse.Object.extend("Post");
var query = new Parse.Query(Post);
query.equalTo("title", title);
return query.find();
}
2) Delete an array of parse objects like this:
Parse.Object.destroyAll(posts);
3) Put the two ideas together (returning a promise to find then delete) like this:
var title = $("#post-remove").val();
postsMatching(title).then(function(posts) {
console.log("deleting " + JSON.stringify(posts));
Parse.Object.destroyAll(posts);
}, function(error) {
console.log("error " + JSON.stringify(error));
});
First of, you can use the Parse.Query.equalTo(key, value) method to filter for the Post/s you are looking for. That will render a lot of your logic unnecessary.
Additionally, since most parse calls are asynchronous, I would suggest learning about Parse Promises and using those instead of the call backs you're using.
Finally, you don't need a second nested query, since you already have the object you are trying to destroy. You just need to call destroy() on that object, and if you have some extra content you need to take care of deleting (i.e., your 'content' is a pointer to another object that is owned only by the Post you are deleting), you should set up a beforeDestroy() trigger for the Post object in your cloud code that will delete that pointer as well.
I'm a new Cordova-Android program maker. I've successfully create and insert the local database fields. But I stuck when I want to display them into input tag.
This is my table :
+----+------+---------+
| id | word | stats |
+----+------+---------+
| 1 | abc | stackov |
| 2 | def | erflow |
+----+------+---------+
I try this code
$(document).ready(function(){
docDB = window.openDatabase("Test", "1.0", "Test Data", 50000);
docDB.transaction(function (tx) {
tx.executeSql("SELECT * FROM Test WHERE word='abc'", [], function (tx, results) {
var dblen = results.rows.length;
if( dblen>0 ){
document.getElementById("abc").value = results.rows.item(0)['stats'];
}
}, null);
});
});
I've searching for simplest way, because I just want to display single SQL column value word='abc' and other word value such word='def'. Can someone correct it?
And I would insert the result value into a input field
Name : <input type="text" id="abc">
Thanks for answering :)
Try adding your search value outside of the SQL statement and refer to the item as an object, see below:
$(document).ready(function(){
docDB = window.openDatabase("Test", "1.0", "Test Data", 50000);
docDB.transaction(function (tx) {
tx.executeSql("SELECT * FROM Test WHERE word=?", ['abc'], function (tx, results) {
var dblen = results.rows.length;
if( dblen>0 ){
document.getElementById("abc").value = results.rows.item(0).stats;
}
}, null);
});
});
Removing the search parameters from the actual SQL statement has a few different benefits. One is, by passing in the variables they are escaped correctly as to not break the statement. Another is, it makes the statement more clear when debugging code.
For those who may not be familiar with the syntax, you add ? where you would place variable input or a search parameter and then in the array after the statement [] items are removed from the array and added to the SQL statement.
Example:
..."SELECT * FROM thisTable WHERE id IN(?) AND name LIKE ? and gender=?", ['1,32,456', '%tim%', 'M']
Generates:
"SELECT * FROM thisTable WHERE id IN('1,32,456') AND name LIKE '%tim%' and gender='M'"
You need to reaffirm the assessment in your sql code
function insertToProject(cast, pName)
{
db.execute('INSERT INTO project (cd, pn) VALUES (?,?)', cast, pName);
var x = last_insert_rowid();
return x;
}
I have been trying this using javascript in titanium appcelerator. Can anybody tell me what I am doing wrong?
For this you can use the lastInsertRowId property of database object.
You can use like:
var x = db.lastInsertRowId;
lastInsertRowId
lastInsertRowId : Number
The identifier of the last populated row
Please check this link for more details : Titanium.Database.DB
You may also do:
db.transaction(function(tx) {
tx.executeSql("INSERT INTO project (cd, pn) VALUES (?,?)", cast,
function(tx, res) {
var id = res.insertId;
});
});
Thus, getting the result of the successful insert and then its property insertId