using placeholder in sql query in asp.net - asp.net

I am an ASP.Net developer & using sql server CE 4.0 I want to know how to use place holder for this code, As this query is currently vulnerable to sql injection. Place holder can prevent this but the problem is for example query = "SELECT * FROM TABLE WHERE TITLE = #0" but in my query the value of #0 is dynamically added to query how do i use place holder
this is the code
if (Request["search"] != "" && Request["search"] != null)
{
var search = Request["search"].Trim();
string[] querynew = search.Split(' ');
var searchquery = "and ";
foreach (string word in querynew)
{
searchquery += "response_table.adtitle LIKE '%" + word + "%' OR ";
}
sql += searchquery.Remove(searchquery.Length - 4);
}
if (Request["min"] != "" && Request["min"] != null && Request["max"] != null && Request["max"] != "")
{
sql = sql + " and (CAST(response_table.price AS Float)) between " + Request["min"].Trim() + " AND " + Request["max"].Trim();
}
// 3. the order clause
switch (Request["sort"])
{
case "recent":
sql = sql + "ORDER BY response_table.response_ID DESC OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
case "hightolow":
sql = sql + "ORDER BY CAST(response_table.price AS Float) Desc OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
case "lowtohigh":
sql = sql + "ORDER BY CAST(response_table.price AS Float) ASC OFFSET " + offset + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY";
break;
default:
break;
}
result = db.Query(sql);
Thank You

Using parameters (instead of concatenating strings) allows you to optimize performance of your queries.
You can use a SqlCeCommand. It has a collection of parameters and you can find a sample here regarding how to use them.

Related

Retrieving Int Value from SQLite database

I am trying to retrieve an integer from my SQLite database and my current query crashes my program. This is what I have so far:
*/
public int getWin(String id){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL3 + " FROM " + TABLE_NAME +
" WHERE " + COL2 + " = '" + id + "'";
Log.d(TAG, "updateName: query: " + query);
db.execSQL(query);
int win = Integer.parseInt(query);
return win;
}
I am not sure why this will not work. Thanks in advance.
You are trying to convert the value SELECT ......... into a number as per int win = Integer.parseInt(query);.
For a SELECT statment you need you need to retrieve a Cursor (result set), via either the query or rawQuery SQLiteDatabase method and then extract the value(s) from the method and to then access the respective column from the respective row(s).
I believe that you would use something like :-
public int getWin(String id){
SQLiteDatabase db = this.getWritableDatabase();
int rv = -1; //<<<<<<<<<< ADDED default value to return if no row found
String query = "SELECT " + COL3 + " FROM " + TABLE_NAME +
" WHERE " + COL2 + " = '" + id + "'";
Log.d(TAG, "updateName: query: " + query);
Cursor csr = db.rawQuery(query,null); //<<<<<<<<<< CHANGED to get the Cursor returned
// ADDED the following IF construct
if (csr.moveToFirst()) {
rv = csr.getInt(csr.getColumnIndex(COL3));
}
//int win = Integer.parseInt(query); //<<<<<<<<<< DELETED (commented out)
csr.close(); //<<<<<<<<<< ADDED should always close a Cursor when done with it
return rv; //<<<<<<<<<< return the value (-1 if no row found)
}
This assumes that you just want the value from a single row as identified by the WHERE clause.
If possible it is recommended to a) not build the query with direct values (makes it vulnerable to SQL Injection) and to b) utilise the convenience query method.
Apply both a and b and your code could be :-
public int getWin(String id){
SQLiteDatabase db = this.getWritableDatabase();
int rv = -1;
String whereclause = COL2 + "=?"; //<<<<<<<<<< where clause without where and ? for value that will be passed
String[] whereargs = new String[]{String.valueOf(id)}; //<<<<<<<<<< arguments used by the whereclause ? replaced on a 1 for 1 basis
String[] columns = new String[]{COL3}; //<<<<<<<<<< the columns to extract as a String array
Cursor csr = db.query(TABLE_NAME,columns,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
rv = csr.getInt(csr.getColumnIndex(COL3));
}
csr.close();
return rv;
}

SQLiteException: near "t": syntax error (code 1):

I'm receiving the following error from my insert db call.
"android.database.sqlite.SQLiteException: near "t": syntax error (code 1): , while compiling: INSERT INTO OCR(bmp, title, description) VALUES ('[B#9430d52', 'Result:', '
pacifism
Enchant creature
Creature can't attack Or
That
—Knrtce of Qal Sima
');
This is my insert statement
String INSERT_TO_DB = "INSERT INTO " + TABLE_NAME + " ("+
COLUMN_BITMAP + ", " +
COLUMN_TITLE + ", " +
COLUMN_DESCRIPTION +") " +
"VALUES ('" + getBytes(ocr.getBitmap()) + "', '" + ocr.getTitle() + "', '" + ocr.getDescription() + "');";
db.execSQL(INSERT_TO_DB);
The thing is it was working on other images, i'm thinking it has something to do with the fact that there's a lot of "/n" in the description it's trying to insert into the db.
Never put string values directly into an SQL statement; use parameters instead.
It is not necessary to use a prepared statement object to achieve this:
db.execSQL("INSERT ... VALUES(?, ?, ?)",
new Object[]{ ocr.getTitle(), ... });
And there is a helper function that constructs the statement for you, and handles binary data correctly:
ContentValues cv = new ContentValues();
cv.put(COLUMN_TITLE, ocr.getTitle());
cv.put(COLUMN_BITMAP, ocr.getBitmap()); // byte array
...
db.insert(TABLE_NAME, null, cv);

what is function/value for updating a row with current time_stamp in sqlite

This is my create table statement.
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_BRANDS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_CREATED_AT + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ KEY_UPDATED_AT + " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" + ")";
as per SQLITE document ON UPDATE CURRENT_TIMESTAMP is not allowed in column definition.
so i thought of passing KEY_UPDATED_AT values while updating a row.
This is my update function.
public int updateBrand(Brand brand) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, brand.getName());
values.put(KEY_UPDATED_AT, ?????)
// updating row
return db.update(TABLE_BRANDS, values, KEY_ID + " = ?",
new String[] { String.valueOf(brand.getId()) });
}
My question is what values should i put values.put(KEY_UPDATED_AT, ?????), to update the row properly.
The ContentValues object allows only literal values.
To do any kind of computation, you must use execSQL instead:
db.execSQL("UPDATE "+TABLE_BRANDS+
" SET "+KEY_NAME+" = ?, "+
KEY_UPDATED_AT+" = CURRENT_TIMESTAMP"+
" WHERE "+KEY_ID+" = ?",
new Object[]{ brand.getName(), brand.getId() });

Log Parser c# error using STRCAT with CASE

I'm having trouble with the log parser, punctually on the use of the function STRCAT parameter with CASE, using log parser the query works perfectly and using a simple STRCAT without CASE the query works even using c#, the problem starts when i use CASE. Am I missing something?
Here's the error:
CLogQueryClass: Error 8007064f: Execute: error parsing query: Syntax Error: : cannot find closing parenthesys for function STRCAT [ SQL query syntax invalid or unsupported. ]
string query = "SELECT " + " STRCAT('" + entry.Name +"'";
query += #", CASE INDEX_OF(SUBSTR(cs-uri-stem,1), '/')
WHEN 'NULL' THEN 'DEFAULTAPPPOOL'
ELSE EXTRACT_TOKEN(cs-uri-stem,1,'/')
END";
query += ") AS APPPOOL";
query += ", '" + Environment.MachineName + "' as server";
query += ", '" + entry.Name + "' as site";
query += ", cs-uri-stem as csUriStem";
query += ", c-ip as cIp, sc-status as scStatus";
query += ", sc-bytes as scBytes";
query += ", cs-bytes as csBytes";
query += ", time-taken as timeTaken";
query += " FROM " + logAddress + "\\" + yesterdayLogName;
// Initialize a LogQuery object
logQuery = new LogQueryClass();
logRecordSet = logQuery.Execute(query,new COMIISW3CInputContextClass());
//SHOWS RESULT
for (; !logRecordSet.atEnd(); logRecordSet.moveNext())
{
logrecord = logRecordSet.getRecord();
int i = 0;
while (i < 9)
{
Console.WriteLine(logrecord.getValue(i));
i++;
}
Thanks
First, it looks like you are mixing types. The CASE INDEX_OF(SUBSTR(cs-uri-stem,1), '/') WHEN 'NULL' compares an integer to string. This should be:
CASE INDEX_OF(SUBSTR(cs-uri-stem,1), '/')
WHEN NULL THEN 'DEFAULTAPPPOOL'
ELSE EXTRACT_TOKEN(cs-uri-stem,1,'/')
END
The error complains about finding the close parenthesis, but I've found that parsing errors can result in misleading error messages with LogParser.
Second, I've tested the following in C# targeted at .NET 3.5 (4.0 had an issue with embedded type. Similar to this...):
string logAddress = "C:\\Path\\to\\consolidatedFile";
string entryName = "blah";
string yesterdayLogName = "fileName.log";
string query = "SELECT " + " STRCAT('" + entryName + "'"
+ ", CASE INDEX_OF(SUBSTR(cs-uri-stem,1), '/') "
+ "WHEN NULL THEN 'DEFAULTAPPPOOL' "
+ "ELSE EXTRACT_TOKEN(cs-uri-stem,1,'/') "
+ "END"
+ ") AS APPPOOL"
+ ", '" + Environment.MachineName + "' as server"
+ ", '" + entryName + "' as site"
+ ", cs-uri-stem as csUriStem"
+ ", c-ip as cIp, sc-status as scStatus"
+ ", sc-bytes as scBytes"
+ ", cs-bytes as csBytes"
+ ", time-taken as timeTaken"
+ " FROM " + logAddress + "\\" + yesterdayLogName;
// Initialize a LogQuery object
COMW3CInputContextClassClass ctx = new COMW3CInputContextClassClass();
//LogQueryClass logQuery = new LogQueryClass();
LogQueryClass logQuery = new LogQueryClassClass();
//ILogRecordset logRecordSet = logQuery.Execute(query, new COMIISW3CInputContextClass());
ILogRecordset logRecordSet = logQuery.Execute(query, ctx);
//SHOWS RESULT
for (; !logRecordSet.atEnd(); logRecordSet.moveNext())
{
ILogRecord logrecord = logRecordSet.getRecord();
int i = 0;
while (i < 9)
{
Console.WriteLine(logrecord.getValue(i));
i++;
}
}
This ran successfully and return results. I commented out the lines initially presented since when I used them nothing returned on the console. That might be a difference of the code not presented. Finally, I substituted a string entryName for the entry.Name object assuming that it returns a string.
I hope this helps.

how to use combination of different fields in query when no of fields are uncertain?

I'm using advance search option in library project
Here is idea :
i have 6 different fields to allow search if i give the option for user to enter value in any of 6 option or enter combined fields how to use sql query to retrieve the value.
For example the fields are author, publication, price, subject, edition, bookid
and if user enter only one value i could search but if user enter more than one if i try combinations then there are many combination.
Please suggest me how to define the query?
you can do something like..
string strFilters = string.Empty;
if (author != "" )
{
strFilters += " Author = " + yourAuthorString + " and ";
}
if (publication != "")
{
strFilters += " publication = " + yourpublicationString + " and ";
}
if (price != "")
{
strFilters += " price = " + priceValue + " and ";
}
if (subject != "")
{
strFilters += " subject = " + yoursubjectString + " and ";
}
if (edition != "")
{
strFilters += " edition = " + youreditionString + " and ";
}
if (strFilters.Length > 3)
{
strFilters = strFilters.Remove(strFilters.Length - 5, 5);
}

Resources