SQLite Parameters - Not allowing tablename as parameter - apache-flex

I'm developing an application in AIR via Flex, but I'm not seeing where I'm going wrong with SQLite (I'm used to MySQL). Parameters work, but only in certain instances. Is this part of the built-in sanitation system against sql injection? Thanks for any help!
Works:
sqlite
"INSERT :Fields FROM Category", where the parameter is :Fields = "*"
as3
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = "INSERT :Fields FROM Category";
statement.parameters[":Fields"] = "*";
statement.execute;
Doesn't Work (SQL syntax error at ":Table"):
sqlite
"INSERT :Fields FROM :Table", where the parameters are :Fields = "*" and :Table = "Category"
as3
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = "INSERT :Fields FROM :Table";
statement.parameters[":Fields"] = "*";
statement.parameters[":Table"] = "Category";
statement.execute;

Generally one cannot use SQL parameters/placeholders for database identifiers (tables, columns, views, schemas, etc.) or database functions (e.g., CURRENT_DATE), but instead only for binding literal values.
With server-side support for parameterized (a.k.a. prepared) statements, the DB engine parses your query once, remembering out the peculiars of any parameters -- their types, max lengths, precisions, etc. -- that you will bind in subsequent executions of the already-parsed query. But the query cannot be properly parsed into its syntactic elements if critical bits, like database objects, are unknown.
So, one generally has to substitute table names oneself, in a stored procedure or in client code which dynamically concats/interpolates/whatevers the SQL statement to be properly executed. In any case, please remember to use your SQL API's function for quoting database identifiers, since the API won't do it for you.

Not sure if this is the same but I ran across something similar in Java. Basically you can't add a table as a parameter so you must generate the statement like so:
var statement:SQLStatement = new SQLStatement();
statement.connection = connection;
statement.text = stringUtil.substitute("INSERT :Fields FROM {0}", "Category");
statement.parameters[":Fields"] = "*";
statement.execute;
This is mostly likely not the securest solution, so you might want to some custom validation of the data before you add the table name.. so someone doesn't try to send it the table name ";drop tableName..."

Related

ASP.NET page can Insert a date to an Access database, but not Update

I have an ASP.NET page that needs to push a little data to an MS Access 2003 database. The process requires a Select on one record, Inserting one new record and Updating one record. I am connecting to the Access database via an OleDbConnection connection. So far, the Select and Insert functions are working exactly as expected (so I know my connection is good). The Update, however, fails to update any rows. The function to update the record looks like this:
public static int UpdateDeviceDates(int deviceId, DateTime nextTestDate)
{
var conn = DbConnect.AccessConnection();
var sqlString = WebConfigurationManager.AppSettings["UpdateDeviceDates"];
using (var cmd = new OleDbCommand(sqlString, conn))
{
cmd.Parameters.AddWithValue("#DeviceID", deviceId);
cmd.Parameters.AddWithValue("#NextTestDate", nextTestDate);
cmd.CommandType = CommandType.Text;
conn.Open();
var result = cmd.ExecuteNonQuery();
return result;
}
}
The sqlString pulled back from the web.config file looks like this:
UPDATE tblDevice
SET tblDevice.NextTestDate = #nextTestDate,
tblDevice.FirstNoticeDate = Null,
tblDevice.SecondNoticeDate = Null
WHERE DeviceID=#deviceId;
This query works fine if you paste it into a new Access query window and hit run, so I know the syntax is correct. I have done quite a bit of testing and figured out that it is the #nextTestDate field that is causing it to fail. When I took that out of the SQL string, it updated the record as expected. This is disconcerting, because the date I pass through to the Insert function works just fine.
I have looked around quite a bit and the closest I found to an answer was "Can't update date in aspx to a MS-ACCESS table". The main answer there was to change the parameter to a ShortDateString. I tried that to no effect. It was also suggested to bracket the date in #, since that is what Access does in its own queries. Unfortunately, that didn't work either.
I don't know why either of these should have been necessary, because the date comes through in exactly the same format as in the Insert statement and that works fine. I'm at my wits end here because the only thing I've found to make that query work is to remove the date parameter (which would defeat the main purpose of the query).
In your query, the parameters are in a different order, the order must match:
cmd.Parameters.AddWithValue("#NextTestDate", nextTestDate);
cmd.Parameters.AddWithValue("#DeviceID", deviceId);
To match:
UPDATE tblDevice
SET tblDevice.NextTestDate = #nextTestDate, <--- Param 1
tblDevice.FirstNoticeDate = Null,
tblDevice.SecondNoticeDate = Null
WHERE DeviceID=#deviceId; <--- Param 2

Entity Framework Update Time & Date Column with Parameterized

I have changed all my code from the raw ADO.NET SQLCommand to Entity Framework in order to have easier accessibility of changing my code in the future. However, I have realized there are many drawbacks in Entity Framework it is not as simple as injecting raw SQL commands into the database. Moreover, I have used Reverse Engineering to generate the Models & Mapping for MS Sql Server.
Currently, I am trying to do the following but none of the columns are getting updated.
string sql = #"UPDATE [ProductDB] SET CreatedProduct_Time=getdate(), CreatedProduct_Date=getdate()" + " WHERE [Material_No] = #Material_No";
db.Database.ExecuteSqlCommand(sql, new SqlParameter("#Material_No", materialnotxt));
The columns are not getting updated.
I am having a doubt whether Entity Framework will help me maintain my code for future use and is it worth the headache using it instead of the old raw SQL code? So far there are many constraints and it requires a higher learning curve.
Some confusing parts I have find online what is the difference between the context.Database.ExecuteSqlCommand and this MSDN http://msdn.microsoft.com/en-us/library/bb738684.aspx the code looks entirely different then my approach.
EDIT
I have used a different approach to insert the Date and Time while inserting all the info from the textbox.
using (var db = new ROGContext())
{
ProductDB product = new ProductDB
{
Material_No = long.Parse(MaterialNo_txtbox.Text),
Product_Line = ProductLineDropDownList1.SelectedItem.Text,
Product_Description = Description_txtbox.Text,
Size = Size_txtbox.Text,
UOM = UOM_txtbox.Text,
SupplierID = long.Parse(SupplierCountryListBox.SelectedItem.Value),
CreatedProduct_Date = DateTime.Parse(System.DateTime.Now.ToShortDateString()), //in the SQL database I have set the datatype as date to get yyyy/mm/dd
CreatedProduct_Time = DateTime.Now.TimeOfDay //in the SQL database I have set the datatype as time(0) to get hh:mm:ss
};
long queryselect = (from materialno in db.ProductDBs
where materialno.Material_No == product.Material_No
select materialno.Material_No).SingleOrDefault();
if (queryselect != long.Parse(materialnotxt))
{
Label1.Text = "Product successfully added in database";
Label1.Visible = true;
db.ProductDBs.Add(product);
db.SaveChanges();
}
You can use Context.ExecuteStoreCommand for Insert, Update and Delete.
See in Page 64 of Entity Framework 4.0 Recipes: A Problem-Solution Approach
Answer your edited part:
ExecuteStoreQuery for Select
ExecuteStoreCommand for Insert, Update and Delete
Entity Framework v4 – Tips and Tricks

DataTableMapping using adapter.FillSchema method applied on a Stored Procedure

this is a method i was reading about #MSDN ,
my question is if for an example i would like to use it on a stored procedure
with the fact that the query of that stored procedure is already specifying columns to select from the table like following :
SELECT Columnsome, columnother, , , , ...FROM thisSQLdbTable
though i would like to implement the approach of that specific method , it seems very advanced from a little research i have made on
"the best way" available to extract data from SQL Server into Asp.net DataTable.
public static DataTable GetCustomerData(string dataSetName,
string connectionString)
{
DataTable table = new DataTable(dataSetName);
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers", connection);
DataTableMapping mapping = adapter.TableMappings.Add("Table", "Customers");
mapping.ColumnMappings.Add("CompanyName", "Name");
mapping.ColumnMappings.Add("ContactName", "Contact");
connection.Open();
adapter.FillSchema(table, SchemaType.Mapped);
adapter.Fill(table);
return table;
}
}
or is it not the method to use if i am querying via SP that specifies the selected column
i could actually drop that stored procedure if it is not requiered to select /specify columns
the stored procedure is doing a specific calculation and updates the table with results of calculation then i am switching it's "MODE" to select results from the table that was updated.
what i did is recyceling (; giving it a parameter (bit type)
stored procedure then asks for the value of supplied bool / bit Parameter,
if its is status true it updates (doing its original task it was made for)
if its false its doing a select oporation so i am using it as i would with 2 separated commands
but now that i have search for a better way to extract data from db into a Data table
i give up on the two way SP and i will make a selection via the exaple above if they're not intended to be used thogether as with my current SP that does preselection when servs the GetCustomersData() above.
So the question is do i need to let the function to make the selection or can i serve it with my sp ready made selection to implemet it with GetCustomersData() in the way that it will only do rest of task and only mapp the columns that was preselected
Still a bit confused on your actual requirement but here goes:
I See you are using a direct query in your C# code, 'best way' would be to make a SP out of it then say:
SqlCommand command = conn.CreateCommand();
SqlDataAdapter sqlAdapter = new SqlDataAdapter(command);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "sp_GetCustomerData";
Then after you have added parameters if needed do:
conn.Open();
sqlAdapter.Fill(dtResult);
conn.Close();
Where dtResult is Datatable.
So you do not need to do any mapping in this case, and since you are using a SP from the Database it will work faster than your direct query and you can change the query logic any time without the need of re deploying your code.
Stored procedures are perfectly valid in this use case. however, if you want more of a properly mapped table, you have several options, some of which go beyond the use of DataTables.
You can use strongly typed DataSets or perhaps use an ORM (object relational mapper).
ref: Typed Datasets: http://msdn.microsoft.com/en-us/library/esbykkzb(v=vs.71).aspx
ref: What is an ORM : http://en.wikipedia.org/wiki/Object-relational_mapping
EXAMPLES OF ORM'S
ref: Entity Framework : http://msdn.microsoft.com/en-us/data/ef.aspx
ref: NHibernate: http://nhforge.org/

MySQL Data Access Layer: How do you store your queries?

I've been building this project as the solo dev for a while, and while I'm comfortable in the front end and middle tier, I don't really think I'm doing the database the way I should be, and the reason why is because I simply don't really know of any other way. The way I'm currently getting data is by testing out queries in my MySQL workbench and copying and pasting the SQL as a string literal into a method that makes a call to the DB, pulls the data and hydrates my objects.
This hasn't really been a problem until recently, when I had to create a monster of a query and it got me thinking that maybe there's a better way to do this. I don't have a formal DAL separated out, so I know there's room for improvement there, but I was curious about what the correct way would be to store SQL strings. I assume there is a tool somewhere built into VS10 where I can manipulate and work with SQL as SQL instead of as a string.
You should be doing this in stored procedures. That will basically format and store your query. You set parameters that are passed in from your code, then read out the results.
Example:
The C# method:
private void SetNote()
{
const string sql = "sp_SelectControllerNoteByID";
using (var conn = MocSystem.GetMocDbConnection())
{
using (var comm = new SqlCommand(sql, conn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add(new SqlParameter("#ControllerNoteID", ControllerNoteId));
try
{
conn.Open();
using (var rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
CommentText = rdr["NoteText"].ToString();
_commentor = new User(new Guid(rdr["NoteAuthor"].ToString()));
CommentDate = (DateTime)rdr["NoteDate"];
MocRequestId = (int)rdr["MocRequestID"];
}
}
}
catch (Exception ex)
{
HasError = true;
ErrorMessage += "\nThere was a problem building the note: " + ex.Message;
}
}
}
}
The stored procedure on the DBMS (sql server in this example):
ALTER proc [dbo].[sp_SelectControllerNoteByID]
#ControllerNoteID int
AS
SELECT
ControllerNoteID,
NoteText,
NoteDate,
NoteAuthor,
MocRequestID
FROM
ControllerNotes
WHERE
ControllerNoteID = #ControllerNoteID
So here we call the stored procedure which in this case is just a simple select statement, then we read it out into an object via ADO. Now, this way, you can modify your query without recompiling. Unless you add parameters, in which case you'll have to update those in your code as well.

Passing databasename to SQL query in webmatrix/razor

I have a form built in webmatrix that will be updating data within a user specified database.
I would like the user to insert their DB name into the form, and have the Database.Open("SQLServerConnectionString"); open based on the users submission.
if not possible, is there a way to simply include the user specified DB name within the SQL query below within webmatrix? Sample of what I have below:
var db = Database.Open("SQLServerConnectionString");
var selectQueryString = "SELECT donor_id,first_name,last_name FROM SUPPORT.dpo.dp WHERE donor_id=#0";
I would like the static "SUPPORT" database in the FROM clause to be updated dynamically based on user input. Any help would be great.
Are you using .mdf files or actual database connection strings? If connection strings you can use the OpenConnectionString method and pass a custom connection string instead of using whats in the web.config.
http://msdn.microsoft.com/en-us/library/gg569301(v=VS.99).aspx
Something like this would probably work:
#{
var databaseName = Request["databaseName"]; //load from request
var connectionString = string.Format("Data Source=.\\SQLExpress;Initial Catalog={0};Integrated Security=True", databaseName);
var providerName = "System.Data.SqlClient";
var db = Database.OpenConnectionString(connectionString, providerName);
var selectQueryString = "SELECT * FROM Product ORDER BY Name";
}
You can just drop the SUPPORT. prefix as its not necessary for the select statement.

Resources