SQLite and QSqlQuery: Quoting bounded values - c++

I want to get entries' date for a given month and year, for that I execute successfully in SQliteman the next query:
SELECT date FROM Entries WHERE strftime('%Y-%m',date) = '2013-04'
To use this query with QSqlQuery I use the following code
query.prepare("SELECT date FROM Entries WHERE strftime('%Y-%m',date) = ':year-:month'");
query.bindValue(":month", QString().sprintf("%02d", month));
query.bindValue(":year", QString::number(year));
But the error "Parameter count mismatch" is raised. That is for the quotes in :year and :month, but I have to use it or the query does not return any result.
How must the query be built if the quotes cannot be used?

You cannot replace parameters inside strings; parameters themselves are entire strings.
Concatenate the strings in SQL:
query.prepare("SELECT ... WHERE strftime(...) = :year || '-' || :month");
You could also construct the entire string beforehand:
query.prepare("SELECT ... WHERE strftime(...) = :yyyymm");
query.bindValue(":yyyymm", month + "-" + year);

Related

Filter a report using query string parameters in the URL - not working because of &

This is my column name and value below.
ASSET_NAME - mats&service
Below is the dax code i use to get data from table and create a link to filter the my page, but it wont work when value(mats&service) in column(ASSET_NAME) has & in it, the link gets terminated at & like this
https:/app.powerbi.com/?filter/somerandomtextand%20andthesemats
and the filter wont work, can someone help me escape this & so that value is accepted and filtered in my page,
RawData =
MAX ('Raw data'[Raw Data])&"?filter=Table/ASSET_NAME eq"&" '"
& MAX ( CurrentData[ASSET_NAME] )&"' and Table/LEVEL1 eq"&" '"
& MAX ( CurrentData[LEVEL])&"' and Table/DOS_NO eq"&" ' "
& MAX ( CurrentData[RULE_NO] )&" ' "
The official documentation has a section how to handle special characters in the values. The & character should be replaced with %26, so instead of mats&service value, try with mats%26service.
When concatenating the strings to construct the URL, use SUBSTITUTE DAX function (or multiple nested or separate calls to it) to replace the special characters in the values, e.g. like this:
Measure =
var AssetName1 = MAX(CurrentData[ASSET_NAME])
var AssetName2 = SUBSTITUTE(AssetName1, "%", "%25")
var AssetName3 = SUBSTITUTE(AssetName2, "+", "%2B")
var AssetName4 = SUBSTITUTE(AssetName3, "&", "%26")
RETURN "?filter=Table/ASSET_NAME eq '" & AssetName4 & "'"
Another option is to add a custom column with "safe" values, which are URL encoded using Uri.EscapeDataString M function:
ASSET_NAME_ENCODED = Uri.EscapeDataString([ASSET_NAME])
and use this column when constructing the URL.

01 number input for date not giving output on system

I can't enter 01 into my c++ input, it will return with empty result but when i type other date such as 12 and 11 it does show in the system.
string month;
cin.ignore(1, '\n');
cout << "Please Enter Month For Example 01 for January:";
getline(cin, month);
string search_query = "SELECT DATE(OrderDate), SUM(TotalPrice) FROM order1 WHERE MONTH(OrderDate) like '%" + month + "%' GROUP BY DATE(OrderDate)";
const char* q = search_query.c_str();
qstate = mysql_query(conn, q);
DATABASE
This is what happen if I enter "01"
This is what happen when I enter "11"
This is when I type "12" it successfully show
The problem is that you are using the LIKE operator in MySQL, which checks to see if the pattern specified on the right occurs in the string specified on the left. The pattern "01" probably doesn't occur in the value on the left, since the string on the left should be "1" for January orders, and that doesn't have a "0" in it.
I also imagine that if you type "1" you would actually see all orders from January, October, November, and December since all those months have "1" in them.
Try using something like MONTH(OrderDate) = 1 instead.
To be more explicit: try changing the line in your program that defined search_query to this:
std::string search_query = "SELECT DATE(OrderDate), SUM(TotalPrice) FROM order1 WHERE MONTH(OrderDate) = " + month + " GROUP BY DATE(OrderDate)";
By the way, for a more robust program, you should also make sure you turn the user-supplied month number into an integer before adding it to the query string; right now you are letting users insert arbitrary strings into your query, which could be dangerous.

warning: missing terminating " character

I'm making a C++ program that connects to an SQL database. This query is really long and probably not the best way to go about it, but that's besides the point. This error is referring to the first " in this code, right before SELECT. Not sure what the problem is considering the ending " is at the end of the function. I'm assuming that I need to use some escape characters somewhere but nowhere that I put them seem to do anything.
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, orderdetails.quantityOrdered, orde
rdetails.priceEach, employees.firstName, employees.lastName, employees.email
AS returnedInfo
FROM customers
JOIN orders ON customers.customerNumber=orders.customerNumber
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
JOIN products ON orderdetails.productCode = products.productCode
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber
WHERE customers.customerNumber = \'103\';");
Literal strings needs to end before the line ends. You can work around that by using the preprocessor line-continuation, as in
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, \orderdetails.quantityOrdered, orderdetails.priceEach, employees.firstName, employees.lastName, employees.email \
AS returnedInfo \
FROM customers \
JOIN orders ON customers.customerNumber=orders.customerNumber \
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber \
JOIN products ON orderdetails.productCode = products.productCode \
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber \
WHERE customers.customerNumber = '103';");
Of use the compilers string-literal concatenation where it concatenates adjacend string literals:
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, orderdetails.quantityOrdered, orderdetails.priceEach, employees.firstName, employees.lastName, employees.email "
"AS returnedInfo "
"FROM customers "
"JOIN orders ON customers.customerNumber=orders.customerNumber "
"JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber "
"JOIN products ON orderdetails.productCode = products.productCode "
"JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber "
"WHERE customers.customerNumber = '103';");
Note that both of these will create what is in reality a single line. If you want to pass it to the function as multiple lines you need to add the newline \n at the end of each "line" yourself. Or use raw string literals as mentioned in the answer by druckermanly.
On a side-note: As you might have noticed, I don't escape the single quoted "string". In double-quoted strings you don't have to escape the single-quote.
You want a raw string literal (introduced in C++11). The problem is that, by default, you can't put an actual newline (instead of \n) in your string, but you can with raw string literals.
If you're not using C++11 or later, you can use other techniques (line continuations, or concatenated sequential strings) but this is often the cleanest way to represent your intent if it's available to you.
Here's an example using your query:
res = stmt->executeQuery(R"SQL(
SELECT
customers.customerNumber,
customers.customerName,
customers.phone,
customers.creditLimit,
orders.orderNumber,
orders.orderDate,
orders.status,
products.productName,
orderdetails.quantityOrdered,
orderdetails.priceEach,
employees.firstName,
employees.lastName,
employees.email
AS returnedInfo
FROM customers
JOIN orders ON customers.customerNumber=orders.customerNumber
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
JOIN products ON orderdetails.productCode = products.productCode
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber
WHERE customers.customerNumber = '103';
)SQL");

Input string was not in correct format.How to correct it?

I have a requirement where i have to remove the drop down items depending upon the start date and end date.
The issue here is, It throws error that input string was not in correct format.
foreach (SPListItem oSPListItemCourse in oSPListItemCollectionCourse)
{
string begginingDate = oSPListItemCourse["Start Date"].ToString();
string finishDate = oSPListItemCourse["End Date"].ToString();
if (( Convert.ToInt32(begginingDate)>=Convert.ToInt32(TxtStartDate.Text) ) || (Convert.ToInt32(finishDate)<= Convert.ToInt32(TxtEndDate.Text)))//input string not in correct format
{
ddlDrop.Items.Remove(ddlDrop.SelectedItem);//how to remove the item from drop down if their date is greater than StartDate and less than EndDate
}
}
Convert the startdate and end date value to DateTime Format rather than to a string.
You are trying to convert date string to integer value. What did you expect as result?
If you want to compare two dates just convert all values to DateTime and compare them.

JPA 2: Change #NamedNativeQuery to CriteriaBuilder equivalent

Is it possible to change this #NamedQuery query:
SELECT #rownum:=#rownum+1 'no', m.title, m.author, REPLACE(SUBSTRING_INDEX(m.content, ' ', 20), '<br>', ' '), m.viewed, m.hashid FROM book m, (SELECT #rownum:=0) r WHERE m.lang = ?1 AND m.title like CONCAT('%',?2,'%') ORDER BY m.title asc
to a CriteriaBuilder equivalent. Or not?...
I think the natural way to do this would be to handle the query in JPA, but to do the numbering and string mangling in Java. The query looks like this:
EntityManagerFactory emf;
String lang;
String keyword;
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Book> criteria = builder.createQuery(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
Since the results come back in a list, you can simply use the index into the list for the 'no' field, and you can write a method getContentSnippet() on Book to do the substringing and replacement.
If you really wanted to do the string mangling in the database, perhaps to reduce the amount of text transferred, then you could write a tuple query, which could retrieve the book and the snippet. Note that i would still retrieve the whole book, rather than individual fields, because this makes subsequent programming so much easier; if you want to avoid having the whole content transferred, mark it for lazy loading in the Book class. The query looks like:
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
final Root<Book> root = criteria.from(Book.class);
final Expression<String> snippetExpr = builder.substring(root.get(Book_.content), 1, 120);
criteria.multiselect(root, snippetExpr);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
I'm using substring to build the snippet, because i'm using PostgreSQL, and that doesn't have an equivalent of the SUBSTRING_INDEX function. You could use CriteriaBuilder.function to call it with MySQL. I'm still not doing the numbering or replacement in the query, because i still think that's better done in code.
EntityManager em = emf.createEntityManager();
TypedQuery<Tuple> q = em.createQuery(criteria);
List<Tuple> booksAndSnippets = q.getResultList();
for (int i = 0; i < booksAndSnippets.size(); ++i) {
Tuple bookAndSnippet = booksAndSnippets.get(i);
int no = i + 1;
Book book = bookAndSnippet.get(root);
String snippet = bookAndSnippet.get(snippetExpr).replace("<br>", " ");
}
I really think you might have an easier time using JPQL, though!