Not sure If I can use this ?-operator in a Mix Up SQL statement for parameter Query. Is there any rule on this? Or I must use ? operator all the way.
Thank
Example:
var allUsers = await db.QueryAsync("Select * From Customer Where CompanyName =?" + " AND Name like '" + txtBxName.Text + "%'", Company);
It is possible to use parameters only for some strings, but that would be silly.
Appending % to a string can be done either in C#:
db.QueryAsync("SELECT ... ? ... Name LIKE ?", Company, txtBxName.Text + "%");
or in SQL:
db.QueryAsync("SELECT ... ? ... Name LIKE ? || '%'", Company, txtBxName.Text);
Related
I have a table with columns;
Fullname,
GroupNo,
Tdate,
Schedule,
Cramount,
Dramount,
Iamount.
I want to select those columns where textbox111.text is greater than formula SUM(Cramount)*26/(SUM(Dramount+Iamount)).
The SQL below give me syntax error, can someone help me please DATABASE IS SQLITE AND PROGRAMMING IN XOJO.
sql= "SELECT Fullname, GroupNo, Tdate, Schedule,( SUM(Cramount)*26)/SUM(Dramount+Iamount) AS ok FROM Trans WHERE Branchcode = '1210 - Loans'GROUP BY LoanID HAVING SUM(Cramount)*26/(SUM(Dramount+Iamount)) < '"TextBox111.text'""
There's a couple things wrong with your SQL string, you've got the single and double quote after the TextBox111.text around the wrong way, and you need to concatenate that control value with "+" as Xojo does not do string interpolation.
Try something like:
sql= "SELECT Fullname, GroupNo, Tdate, Schedule, (SUM(Cramount)*26)/SUM(Dramount+Iamount) AS ok FROM Trans WHERE Branchcode = '1210 - Loans' GROUP BY LoanID HAVING SUM(Cramount)*26/(SUM(Dramount+Iamount)) < '" + TextBox111.text + "'"
I'm pretty sure that SQLite supports using the alias for the agregate field in the having clause...
sql= "SELECT Fullname, GroupNo, Tdate, Schedule, (SUM(Cramount)*26)/SUM(Dramount+Iamount) AS ok FROM Trans WHERE Branchcode = '1210 - Loans' GROUP BY LoanID HAVING ok < '" + TextBox111.text + "'"
Your SQL also references two fields that you don't mention in as being in your table, Branchcode and LoanID, hopefully you just forgot to mention them.
I'm attempting a query to get the latest N messages in a particular conversation from a table of messages. I think this is the correct sql:
select * from
(select * from messages where convoId = to order by timestamp DESC limit 10)
order by timestamp ASC;
I have attempted this in sqlite.swift:
static let table = Table("messages")
let query = (table.filter(convoId == to).order(timestamp.desc).limit(10)).select(table[*]).order(timestamp.asc)
which is not working once the amount of messages goes past the limit. Is there any way to see what sql is produced by the sqlite.swift query? Any suggestions?
EDIT: I have also attempted the raw SQL query but now I'm not sure how to extract the result. I feel like this should be a last resort:
let toQuoted = "'" + to + "'"
let subQueryStr: String = [
"(SELECT * FROM",
MessageDataHelper.TABLE_NAME,
"WHERE",
MessageDataHelper.CONVO_ID, "=", toQuoted, "ORDER BY", MessageDataHelper.TIMESTAMP, "DESC LIMIT", String(5), ")"
].joined(separator: " ")
let queryStr: String = [
"SELECT * FROM",
subQueryStr,
["ORDER BY", MessageDataHelper.TIMESTAMP, "ASC;"].joined(separator: " ")
].joined(separator: "\n")
let stmt = try db.prepare(queryStr)
for row in stmt {
// ? how can this be used to create model structure
for (index, name) in stmt.columnNames.enumerate() {
print ("\(name)=\(row[index]!)")
}
}
row[index] is of type Binding, so I'm unsure how to retrieve the value there. Help please!
Thanks
Okay, so looks like sub query might be too complex to express in sqllite.swift. I ended up going with the raw sql query. You can retrieve the result by casting the binding as mentioned here:
Getting results from arbitrary SQL statements with correct binding in SQLite.swift
I am inserting record in db using below mentioned query but it gives me error "Invalid number" so guide me.
string query1 = "insert into MNE.MNE_users(USER_ID,INSERTED_DATE) values ( '" + id + "',to_date('" + INSERTED_DATE.Text + "','DD/MM/YYYY') )";
Please guide me.
to_date() function solves my Problem
I think you should replace; 'yyyy-mm-dd + ' with 'yyyy-mm-dd'
Read this:
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
On the dynamic sql part it has various such as this:
So, if you had an existing Dynamic query being generated in your code that was going to Oracle that looked like this:
String query = "SELECT user_id FROM user_data WHERE user_name = '" + req.getParameter("userID")
+ "' and user_password = '" + req.getParameter("pwd") +"'";
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}
You would rewrite the first line to look like this:
Codec ORACLE_CODEC = new OracleCodec();
String query = "SELECT user_id FROM user_data WHERE user_name = '" +
ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("userID")) + "' and user_password = '"
+ ESAPI.encoder().encodeForSQL( ORACLE_CODEC, req.getParameter("pwd")) +"'";
And it would now be safe from SQL injection, regardless of the input supplied.
But the later is says:
Oracle 10g escaping
An alternative for Oracle 10g and later is to place { and } around the string to escape the entire string. However, you have to be careful that there isn't a } character already in the string. You must search for these and if there is one, then you must replace it with }}. Otherwise that character will end the escaping early, and may introduce a vulnerability.
I did not see an example, but does this mean I can use braces instead of the Codec ORACLE_CODEC....etc.? Does anyone have an example? Thanks.
No, this is not an injection prevention technique. The only way to be 100% sure that you're not vulnerable to injection is to use prepared statements and bind parameters for all user input that needs to be inserted into the query. Anything less than that, and you're pretty much just rolling the dice.
I am writing a query to allow a user to search on what they provide keywords in asp.net, C# and mssql:
string projectPart = null;
string categoryPart = null;
string descriptionPart = null;
if (this.Textbox_ProjectNr.Text.Trim().Length > 0)
projectPart = " AND Number='" + this.Textbox_ProjectNr.Text.Trim() + "' ";
if (this.Textbox_Category.Text.Trim().Length > 0)
categoryPart = " AND Category LIKE '%" + this.Textbox_Category.Text.Trim() + "%' ";
if (this.Textbox_pDescription.Text.Trim().Length > 0)
descriptionPart = " AND ProductDescription LIKE '%" + this.Textbox_pDescription.Text.Trim() + "%' ";
string query = "SELECT * from Project = p.ID " + projectPart + descriptionPart + categoryPart;
I dont know whether this query is sufficient for a traditional query search. Because I see there are some bottlenecks of this search:
if the user does not type anything, it returns all of the data => For this I only do the query when one of the fields are filled.
if the user provides some keywords "P" for each field, the result will be millions of data.
I dont know how to improve the search query basically. any suggestions are appreciated.
Thanks in adavance.
The most important improvement is to protect you code against SQL injection attacks.
You should not concatenate the raw input in the SQL string. If someone searches for the following text for example:
Bwah ha ha'; DROP DATABASE northwind; PRINT'
This will be added to your query to produce
SELECT *
FROM mytable
WHERE category LIKE '%Bwah ha ha'; DROP DATABASE northwind; PRINT'%'
This is a valid SQL command and will happily execute and drop your database (or do anything else the attacker wants)
For more information see SQL Injection and Santitizng Inputs.
You must make this query injection proof! Do not concatenate user entered values, but use parameters, like this:
SqlCommand cmd = new SqlCommand(#"
SELECT * from Project
WHERE
( Number = #Number OR #Number IS NULL ) AND
( Category LIKE #Category OR #Category IS NULL ) AND
( ProductDescription LIKE #ProductDescription OR #ProductDescription IS NULL )", conn);
if(!String.IsNullOrEmpty(this.Textbox_ProjectNr.Text.Trim()))
cmd.Parameters.AddWithValue("#Number", this.Textbox_ProjectNr.Text.Trim());
if(!String.IsNullOrEmpty(this.Textbox_Category.Text.Trim()))
cmd.Parameters.AddWithValue("#Category", this.Textbox_Category.Text.Trim());
if(!String.IsNullOrEmpty(this.Textbox_pDescription.Text.Trim()))
cmd.Parameters.AddWithValue("#ProductDescription", this.Textbox_pDescription.Text.Trim());
Also, you can add some client validation on user entered values. For instance, ask for more than three (?) characaters before running that query.
<asp:TextBox ID="Textbox_ProjectNr" runat="server" />
<asp:RegularExpressionValidator ID="Textbox_ProjectNr_Validator" runat="server"
ControlToValidate="Textbox_ProjectNr"
ErrorMessage="Minimum length is 3"
ValidationExpression=".{3,}" />
First of all, you must protect yourself from sql injections. You haven't specified what connection to the database you are using but most libraries allow adding the parameters in a different field, so they are sanitized automatically.
Secondly, you can (and should) limit the results count using the "LIMIT" (for mysql) or "TOP X" Like so:
Select * from TableName LIMIT 100 or Select TOP 100 * from TableName