How to bind parameters via ODBC C#? - c#

I need to bind parameters on ODBC query from C#. This is the sample code, but VS tells me that there's one parameter missing.
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM user WHERE id = #id";
cmd.Parameters.Add("#id", OdbcType.Int).Value = 4;
OdbcDataReader reader = cmd.ExecuteReader();
What is the syntax for binding values on ODBC?

Odbc cannot use named parameters. This means that the command string uses placeholders for every parameter and this placeholder is a single question mark, not the parameter name.
OdbcCommand.Parameters
Then you need to add the parameters in the collection in the same order in which they appear in the command string
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM [user] WHERE id = ?";
cmd.Parameters.Add("#id", OdbcType.Int).Value = 4;
OdbcDataReader reader = cmd.ExecuteReader();
You have also another problem, the USER word is a reserved keyword per MS Access Database and if you want to use that as field name or table name then it is required to enclose every reference with square brackets. I strongly suggest, if it is possible, to change that table name because you will be hit by this problem very often.

use "?" in place of # if you are using ODBC.
Try to do as follows:
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM user WHERE id = ?";
cmd.Parameters.Add("#id", OdbcType.Int).Value = 4;
OdbcDataReader reader = cmd.ExecuteReader();

To use ODBC parameterized LIKE carry out as follows, i.e. you do not use the typical single quotes or even put the % in the CommandText (Furthermore I think perhaps the %? has a special meaning for Oracle? :
OdbcCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM [user] WHERE name LIKE ?";
cmd.Parameters.AddWithValue("#fieldName", OdbcType.NVarChar).Value = "%" + nameFilter + "%";

Related

How do I escape a table whose name is a reserved SQL keyword?

I've been working with databases in my WPF Application and when I try to execute my command it keeps giving me an SqlException. It's some kind of typing error and it's probably very silly but i've been stuck on this for a while and just cannot figure it out.
string selectStatement = "SELECT * FROM Order ORDER BY OrderDate DESC;";
SqlCommand command = new SqlCommand(selectStatement, connection);
SqlDataReader reader = null;
try
{
connection.Open();
reader = command.ExecuteReader();
This is a picture of the table:
!(https://imgur.com/7oimusw)
const string selectStatement = "SELECT * FROM [Order] ORDER BY OrderDate DESC;";
should fix it
SQL Server: use it between [] (SELECT * FROM [Order];)
Oracle: use it between "" (SELECT * FROM "Order") <- Just watch out that it becomes case sensitive.

Error with SQLDataReader

C#, Razor
my code is:
#using (SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True"))
{
using(connection)
{
SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"]);
connection.Open();
SqlDataReader reader = command.ExecuteReader(); //ERROR!!!
while (reader.Read())
{
string ID = reader["KategorieID"].ToString() ;
Console.WriteLine("ID = {0}", ID);
}
reader.Close();
};
}
i get an error that there's a wrong syntax near "=".
how can i solve this?
The problem is caused by the missing quotes around the value passed for your search. You could add a set of single quote before and after the value obtained by the Request but that would be a bigger error and the source of a problem called Sql Injection.
The only way to handle this is to use a parameter query
SqlCommand command = new SqlCommand(#"SELECT KategoryID FROM Kategory
WHERE Name = #name", connection);
command.Parameters.Add("#name", SqlDbType.NVarChar).Value = Request.Params["kategory"];
Also, as noted in another answer, your code seems to not have associated the connection to the command, I think that it is just a typo here because the error message in that case would be 'need an open connection'
You forgot to assign the connection to the command. So when you call ExecuteReader(), it does not know on which connection it should be executed.
You can assign the connection like this:
SqlCommand command = new SqlCommand(
"SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"],
connection); // provide connection as second parameter!
or use connection.CreateCommand() to create your command.
Second, you forgot the quotation marks around your string:
"SELECT KategoryID FROM Kategory WHERE Name = '" + Request.Params["kategory"] + "'"
but inserting user data directly into your query opens your code to SQL Injection. Please use parameterized queries instead.
If your kategory column is not of integer data type then you need to surround your value with (') i.e single quote characters
Then your query will be like
SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name ='" + Request.Params["kategory"] + "'");
The exception is caused by how you are creating your sql statement. The fix should not be correcting the syntax but using parameters instead. This will prevent sql injection attacks.
Also
You really should not be writting sql in your views, do it in your controller method instead and return the result in the Model to be used in your view. Better yet, abstract it to a different layer and call that layer from your controller. This has to do with SoS (Separation of Concerns), your code will very difficult to maintain if you just write everything into your views.
Wrap your connections, commands, and readers in using blocks.
Modified Code
#{
using(SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True"))
using(SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = #name", Praktikum2))
{
command.Parameters.Add(new SqlParameter("#name", SqlDbType.VarChar){ Value = Request.Params["kategory"]});
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string ID = reader["KategorieID"].ToString() ;
Console.WriteLine("ID = {0}", ID);
}
}
}
}

Generating SQL queries safely in C#

What's the safest way of generating SQL queries in C#, including cleansing user input so it's safe from injection? I'm looking to use a simple solution that doesn't need external libraries.
Use Sql Parameters:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter(v=vs.80).aspx
Here's an example in C#
SqlCommand tCommand = new SqlCommand();
tCommand.Connection = new SqlConnection("YourConnectionString");
tCommand.CommandText = "UPDATE players SET name = #name, score = #score, active = #active WHERE jerseyNum = #jerseyNum";
tCommand.Parameters.Add(new SqlParameter("#name", System.Data.SqlDbType.VarChar).Value = "Smith, Steve");
tCommand.Parameters.Add(new SqlParameter("#score", System.Data.SqlDbType.Int).Value = "42");
tCommand.Parameters.Add(new SqlParameter("#active", System.Data.SqlDbType.Bit).Value = true);
tCommand.Parameters.Add(new SqlParameter("#jerseyNum", System.Data.SqlDbType.Int).Value = "99");
tCommand.ExecuteNonQuery();
In essence don't do this
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = '" + TextBox1.Text + "'"
...
do
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = #MyValue";
command.Parameters.AddWithValue("MyValue",TextBox1.Text);
...
Basically never build your sql command directly from user input.
If you use an ORM, such as EntityFrameworks / POCO all queries are done in the latter form.
The first rule of thumb is to make sure you use parameterized queries/commands. Basically don't dynamically build a sql string that includes something that the user has input into the page.
If you use on ORM (EF, L2S, Nhib), this is typically handled in most cases because most all of them run parameterized queries.
Parametrize your queries.
In case if you build some TSQL which builds some other dynamic TSQL - then use some described technique
What does "parametrizing means?
See, not use something like this:
sqlCommand.CommandText = "select * from mytable where id = "+someVariable;
use this:
sqlCommand.CommandText = "select * from mytable where id = #id";
sqlCommand.Parameters.AddWithValue("#id", someVariable);
Make use of Parametrized Queries.
Simple Example.
var sql = "SELECT * FROM MyTable WHERE MyColumn = #Param1";
using (var connection = new SqlConnection("..."))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#Param1", param1Value);
return command.ExecuteReader();
}
More Detailed Example.
protected void btnGoodAddShipper_Click(object sender, EventArgs e)
{
string connStr = c
"Server=(local);Database=Northwind;Integrated Security=SSPI";
// this is good because all input becomes a
// parameter and not part of the SQL statement
string cmdStr =
"insert into Shippers (CompanyName, Phone) values (" +
"#CompanyName, #Phone)";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
// add parameters
cmd.Parameters.AddWithValue
("#CompanyName", txtCompanyName.Text);
cmd.Parameters.AddWithValue("#Phone", txtPhone.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
Using DBML and LINQ to handle it for you. Many people have worked on those to ensure those issues are well mitigated.
And if not than at least parametrize your queries.
A proper name for DBML is linq2sql or an advanced version is called entity framework. These technologies are provided by Microsoft and well integrated with visual studio. Does not require additional libraries.
Pretty stable products..

SQL query error - "Column cannot be null"

I have a SQL query:
String S = Editor1.Content.ToString();
Response.Write(S);
string sql = "insert into testcase.ishan(nmae,orders) VALUES ('9',#S)";
OdbcCommand cmd = new OdbcCommand(sql, myConn);
cmd.Parameters.AddWithValue("#S", S);
cmd.ExecuteNonQuery();
Error: Column 'orders' cannot be null at System.Data.Odbc.OdbcConnection.HandleError
From the manual:
When CommandType is set to Text, the .NET Framework Data Provider for ODBC does not support passing named parameters to an SQL statement or to a stored procedure called by an OdbcCommand. In either of these cases, use the question mark (?) placeholder. For example:
SELECT * FROM Customers WHERE CustomerID = ?
The order in which OdbcParameter objects are added to the OdbcParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
Use this:
string sql = "insert into testcase.ishan(nmae,orders) VALUES ('9', ?)";
OdbcCommand cmd = new OdbcCommand(sql, myConn);
cmd.Parameters.AddWithValue("you_can_write_anything_here_its_ignored_anyway", S);
cmd.ExecuteNonQuery();
it will be helpful to you
cmd.Parameters.Add("#S", OdbcType.Char, S);

C# Assembly Injection Check

I'm creating an assembly in C# for MS SQL 2005. This assembly creates a stored procedure and runs a dynamic query based on parameters passed into the stored procedure.
Is there a simple function in C# to prevent SQL injection?
For example
string myQuery = "SELECT * FROM dbo.MyTable WHERE lastName = '" + injectionCheck(arg1) + "'";
This question was answered for the standard query... but in situations where there is no way around building a truely dynamic query what can I use in C# for injection checking?
For example, these probably wont work:
using #dbName;
SELECT * FROM #table
OPEN SYMMETRIC KEY #keyName
etc
Use bound parameters:
SqlCommand cmd = new SqlCommand(myQuery, conn);
cmd.Parameters.Add("#lastname", SqlDbType.NVarChar, 10, lastName);
Use parameters ....
(This has been posted often already)
string myQuery = "SELECT * FROM myTable WHERE lastname = #p_name";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = myQuery;
cmd.Parameters.Add ("#p_name", SqlDbType.Varchar).Value = "melp";

Categories

Resources