Below is the code for my Select * Function - It WORKS well and does everything great until i change the SQL string from Select * From Company to
query = "Select * From #1";
and then do the following
query = "Select * From #1";
OleDbCommand Command = new OleDbCommand(query, sqlConnStr);
DataTable Table = new DataTable();
DataSet dataSet = new DataSet();
Table = null;
//Add Parameters
Command.Parameters.AddWithValue("#1", SQLTables.Company);
try
{
Command.ExecuteNonQuery();
adapter.SelectCommand = Command;
adapter.Fill(dataSet);
Table = dataSet.Tables[0];
}
catch (Exception e)
{
MessageBox.Show("A Error occured whilst trying to execute the command.\n" + e.Message);
}
return Table;
The DBMS keeps sending back "Query incomplete" - I assume The Command variable is sending the string query through without changing the Parameter from #1 to Company
Here is a piece of code (mine) where this does work. This is an insert statement rather that a select - Correct me if i am wrong but should it not also work with the SELECT aswell
private void MainActionsInsert(string Action, bool Checked)
{
OleDbCommand Command = new OleDbCommand("INSERT INTO MainActions Values (ID, Action, BoolValue)", DataBaseConnection);
//Add Parameters
Command.Parameters.AddWithValue("ID", GenerateID());
Command.Parameters.AddWithValue("Action", Action);
Command.Parameters.AddWithValue("BoolValue",Checked);
//Add Command
MainActionsAdapter.InsertCommand = Command;
//Execute Agains DataBase
Command.ExecuteNonQuery();
//Accept Changes
}
`
OLEdb doesn't recognize named parameters. You must use ? in the query text.
However, you also can't use dynamic table names with parameterized queries, so even using a ? will not help.
You need to use full dynamic SQL, though that can open you up to SQL Injection. Make sure you read the full article I linked.
OleDbCommand Does accept Parameterized SQL just not in the From Clause - It Has to be either in a WHERE clause or something like that. Like you said it Worked with the insert function because it expects "parameters" there. For example this will work
query = "Select * From Company Where #param = 1";
OleDbCommand Command = new OleDbCommand(query, sqlConnStr);
DataTable Table = new DataTable();
DataSet dataSet = new DataSet();
Table = null;
//Add Parameters
Command.Parameters.AddWithValue("param", "ID");
try
{
Command.ExecuteNonQuery();
adapter.SelectCommand = Command;
adapter.Fill(dataSet);
Table = dataSet.Tables[0];
}
catch (Exception e)
{
MessageBox.Show("A Error occured whilst trying to execute the command.\n" + e.Message);
}
return Table;
Funny though that it doesn't work for the Select part though
Related
I am using sap.net web form. In this web form i have a text and a button. user enter name or id and hit search button. Searching with id is working fine but with name it is not working.
What i am missing here help me out please.
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
try
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR DriverID = #search) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#search", SearchTextBox.Text);
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
catch (SqlException exe)
{
throw exe;
}
}
}
The code is generating an exception. The fact that you're unaware of this indicates that you have "error handling" somewhere in your system that is, in fact "error hiding". Remove empty catch blocks, or pointless catch blocks such as the one in your question that just destroys some information in the exception and re-throws it. Those aren't helping you.
The actual problem is that the DriverID column is int and your parameter is varchar. So long as the varchar contains a string that can be converted to a number (which is the direction that the conversion happens in due to precedence), the query is well-formed.
As soon as the parameter contains a string that cannot be implicitly converted to a number, SQL Server generates an error that .NET turns into an exception.
For your LIKE variant, you're forcing a conversion in the opposite direction (numeric -> varchar) since LIKE only operates on strings. That conversion will always succeed, but it means that you're performing textual comparisons rather than numeric, and also means there's no possible index usage here.
I'd suggest that you change your C# code to attempt a int.TryParse on the input text and then uses two separate parameters to pass strings and (optionally) their numeric equivalent to SQL Server. Then use the appropriate parameters in your query for each comparison.
Something like:
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR " +
"DriverID = #driverId) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#search", SqlDbType.VarChar,50).Value = SearchTextBox.Text;
cmd.Parameters.Add("#driverId", SqlDbType.Int);
int driverId;
if(int.TryParse(SearchTextBox.Text, out driverId))
{
cmd.Parameters["#driverId"].Value = driverId;
}
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
"SELECT * from Driver where (Name LIKE '%" + #search + "%'
OR DriverID = '" + #search + "' ) AND Status = 'Active'";
how about this?
We are using 3-Tier Architecture in ASP.Net.
There are 3 Layers
Presentation
Business
Data Access
The Data Access Layer contains the GetData and ExecuteQuery etc function.
What I want to know is that, that want to call the View directly from the Presentation Layer. Is there any chance of SQL injection in calling a view from front-end without using stored procedure?
Presentation Layer (C#)
protected void btnView_Click(object sender, EventArgs e)
{
DL obj = new DL();
DataTable tb = new DataTable();
string query = "select * from ViewTeacher where FID = " + txtName.Text;
tb = obj.GetData(query);
}
DBAccess
public DataTable GetData(string query)
{
DataTable datatable = new DataTable();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = query;
try
{
if (cmd.Connection.State != ConnectionState.Open)
{
cmd.Connection.Open();
}
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(datatable);
}
}
catch (Exception ex)
{
throw new ArgumentException(ex.Message);
}
return datatable;
}
How are you "calling a view"? If you're running an ad-hoc query of:
SELECT <columns> FROM View WHERE ColumnX = 'Y'
and if that query is being constructed using (potentially) hostile input then yes, of course that can be subject to SQL injection - the whole point of injection is that the attacker can change the nature of the query:
SELECT <columns> FROM View WHERE ColumnX = 'Z'
UNION ALL
SELECT name,0,0,0,0 FROM INFORMATION_SCHEMA.TABLES --'
The attacker isn't limited to just the objects that are present in the original query.
The untrustworthy input in the two above queries was:
Y
and
Z'
UNION ALL
SELECT name,0,0,0,0 FROM INFORMATION_SCHEMA.TABLES --
As you are writing the query as follows that takes value from a textbox, 100% there is posibility for sql injection.
string query = "select * from ViewTeacher where FID = " + txtName.Text;
There should be no chance of SQL Injection while calling a view from front end, as views don't take parameters.
reference :
can we pass parameter to a view in sql?
I am trying to do create a where clause to pass as a parameter to an Oracle command and it's proving to be more difficult than I thought. What I want to do is create a big where query based off user input from our application. That where query is to be the single parameter for the statement and will have multiple AND, OR conditions in it. This code here works however isn't exactly what I require:
string conStr = "User Id=testschema;Password=pass12341;Data Source=orapdex01";
Console.WriteLine("About to connect to Database with Connection String: " + conStr);
OracleConnection con = new OracleConnection(conStr);
con.Open();
Console.WriteLine("Connected to the Database..." + Environment.NewLine + "Press enter to continue");
Console.ReadLine();
// Assume the connection is correct because it works already without the parameterization
String block = "SELECT * FROM TEMP_VIEW WHERE NAME = :1";
// set command to create anonymous PL/SQL block
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = con;
// since execurting anonymous pl/sql blcok, setting the command type
// as text instead of stored procedure
cmd.CommandType = CommandType.Text;
// Setting Oracle Parameter
// Bind the parameter as OracleDBType.Varchar2
OracleParameter param = cmd.Parameters.Add("whereTxt", OracleDbType.Varchar2);
param.Direction = ParameterDirection.Input;
param.Value = "MY VALUE";
// Get returned values from select statement
OracleDataReader dr = cmd.ExecuteReader();
// Read the identifier for each result and display it
while (dr.Read())
{
Console.WriteLine(dr.GetValue(0));
}
Console.WriteLine("Selected successfully !");
Console.WriteLine("");
Console.WriteLine("***********************************************************");
Console.ReadKey();
If I change the lines below to be the type of result I want then I get an error "ORA-00933: SQL command not properly ended":
String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";
My question is how do I accomplish adding my big where query dynamically without causing this error?
Sadly there is no easy way to achieve this.
One thing you will need to understand with parameterised SQL in general is that bind parameters can only be used for values, such as strings, numbers or dates. You cannot put bits of SQL in them, such as column names or WHERE clauses.
Once the database has the SQL text, it will attempt to parse it and figure out whether it is valid, and it will do this without taking any look at the bind parameter values. It won't be able to execute the SQL without all of the values.
The SQL string SELECT * FROM TEMP_VIEW :1 can never be valid, as Oracle isn't expecting a value to immediately follow FROM TEMP_VIEW.
You will need to build up your SQL as a string and also build up the list of bind parameters at the same time. If you find that you need to add a condition on the column NAME, you add WHERE NAME = :1 to the SQL string and a parameter with name :1 and the value you wish to add. If you have a second condition to add, you append AND ID = :2 to the SQL string and a parameter with name :2.
Hopefully the following code should explain a little better:
// Initialise SQL string and parameter list.
String sql = "SELECT * FROM DUAL";
var oracleParams = new List<OracleParameter>();
// Build up SQL string and list of parameters.
// (There's only one in this somewhat simplistic example. If you have
// more than one parameter, it might be easier to start the query with
// "SELECT ... FROM some_table WHERE 1=1" and then append
// " AND some_column = :1" or similar. Don't forget to add spaces!)
sql += " WHERE DUMMY = :1";
oracleParams.Add(new OracleParameter(":1", OracleDbType.Varchar2, "X", ParameterDirection.Input));
using (var connection = new OracleConnection() { ConnectionString = "..."})
{
connection.Open();
// Create the command, setting the SQL text and the parameters.
var command = new OracleCommand(sql, connection);
command.Parameters.AddRange(oracleParams.ToArray());
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do stuff with the data read...
}
}
}
I am trying to write three variables into a database table. The code I have is:
sqlCmd.CommandText = "INSERT INTO dbo.PortfolioValues(StudentNumber,TimeStamp,PortfolioValue) VALUES(StudentNumber.ToString() , Time.ToString() , Total.ToString())" + dbConnection;
sqlCmd.ExecuteNonQuery();
sqlTran.Commit();
dbconnection is the name of the connection. It does not do anything. It is in a try-catch but goes straight to catch.
Thanks in advance.
You should
avoid concatenating together your SQL statement - avoid SQL injection attacks! Use parametrized queries instead!
use using blocks for your SqlConnection and SqlCommand objects
Try something like this:
string _connString = "........";
string queryStmt =
"INSERT INTO dbo.PortfolioValues(StudentNumber, TimeStamp, PortfolioValue) " +
"VALUES(#StudentNumber, #TimeStamp, #TotalValue)";
using(SqlConnection _con = new SqlConnection(_connString))
using(SqlCommad _cmd = new SQlCommand(queryStmt, _con))
{
// create paramters and set values
_cmd.Parameters.Add("#StudentNumber", SqlDbType.Int).Value = StudentNumber;
// do the same for the other two parameters
try
{
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
catch(Exception exc)
{
// handle exception
}
}
StudentNumber.ToString() cannot be contained in a query! It's java code not sql...
//Am asuming you are using C# and the System.Data.SqlClient
//here is how you might do what you want
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
//so that you use it this way:
String query = String.Formart("INSERT INTO dbo.PortfolioValues(StudentNumber,TimeStamp,PortfolioValue) VALUES(\"{0}\",\"{1}\",\"{2}\")",StudentNumber.ToString() , Time.ToString() , Total.ToString());
String connectionString = "your connection string";
CreateCommand(query,connectionString);
Consider the following code:
StringBuilder textResults = new StringBuilder();
using(SqlConnection connection = new SqlConnection(GetEntityConnectionString()))
{
connection.Open();
m.Connection = connection;
SqlDataReader results = m.ExecuteReader();
while (results.Read())
{
textResults.Append(String.Format("{0}", results[0]));
}
}
I used Activity Monitor within Sql Server Mgmt Studio on the database to inspect the exact query that was being sent. I then copied that query text to a query editor window within SSMS, and the query returned the expected results. However, SqlDataReader results is always empty, indicating "The enumeration returned no results."
My suspicion is that somehow the results are not being returned correctly, which makes me think there's something wrong with the code above, and not the query itself being passed.
Is there anything that would cause this in the code above? Or something I've overlooked?
EDIT:
Here is the query as indicated by the SQLCommand object:
SELECT DISTINCT StandardId,Number
FROM vStandardsAndRequirements
WHERE StandardId IN ('#param1','#param2','#param3')
ORDER BY StandardId
Here is the query as it appears in Activity Monitor:
SELECT DISTINCT StandardId,Number
FROM vStandardsAndRequirements
WHERE StandardId IN ('ABC-001-0','ABC-001-0.1','ABC-001-0')
ORDER BY StandardId
The query is working against a single view.
When I ran the second query against the database, it returned 3 rows.
The SqlDataReader indicates 0 rows.
try to use Sqldata adapter instead of sqldatreader.
StringBuilder textResults = new StringBuilder();
using (var conn = new SqlConnection(GetEntityConnectionString())))
{
using (
var cmd = new SqlCommand(
"SELECT DISTINCT StandardId,Number" +
"FROM vStandardsAndRequirements " +
"WHERE StandardId IN (#param1,#param2,#param3)" +
"ORDER BY StandardIdl"
, conn))
{
var dSet = new DataSet();
var dt = new Datatable();
var da = new SqlDataAdapter(cmd);
cmd.Parameters.Add("#param1", SqlDbType.VarChar, 50).Value = "ABC-001-0";
cmd.Parameters.Add("#param2", SqlDbType.VarChar, 50).Value = "ABC-001-0.1";
cmd.Parameters.Add("#param3", SqlDbType.VarChar, 50).Value = "ABC-001-0";
try
{
da.Fill(dSet);
dt = dSet.Tables[0];
foreach(Datarow a in dt.Rows)
{
textResults.Append(a["StandardId"].tostring()).AppendLine();
}
Messabox.Show(textResults.tostring);
}
catch (SqlException)
{
throw;
}
finally
{
if (conn.State == ConnectionState.Open) conn.Close();
}
}
}
Regards.
Are you sure it is
WHERE StandardId IN ('#param1','#param2','#param3')
instead of this?
WHERE StandardId IN (#param1,#param2,#param3)
Parameters should not be quoted, not in the SQLCommand object.
Very nice behavior I've observed
I looked for errors in code:
... dr = command.ExecuteReader() ... If dr.Read Then ...
and found that 'dr.Read' works fine, but...
when I mouseover on 'dr', to lookup for data, return values disappeared !
Check your connection string and make sure you are not connecting as a user instance.
http://msdn.microsoft.com/en-us/library/ms254504.aspx