A Parameter is missing. [Parameter ordinal = 1] - c#

So i've been making a simple c# win forms application for something league of legends related and i've been using a .SDF Database which I'm very new with.
When trying to make a search option I came across this error:
A Parameter is missing. [Parameter ordinal = 1]
Here is my Code: (I did Add the Parameter to the command.)
public DataTable GetDataTableSummoners(string Summoner, string Champion)
{
DataTable t = new DataTable();
try
{
var cmd = new SqlCeCommand();
cmd.CommandText = "SELECT * FROM Summoner";
if (!String.IsNullOrEmpty(Summoner))
{
SqlCeParameter param = new SqlCeParameter();
param.ParameterName = "#Summoner";
param.Value = Summoner;
cmd.Parameters.Add(param);
cmd.CommandText = "SELECT * FROM Summoner WHERE name = #Summoner";
}
var adapter = new SqlCeDataAdapter(cmd.CommandText, conn);
adapter.Fill(t);
}
catch (System.Data.SqlServerCe.SqlCeException ex)
{
System.Diagnostics.Debug.Print("Error: " + ex.Message);
}
return t;
}

You're adding the parameter to the command - but then you're ignoring the command itself here:
var adapter = new SqlCeDataAdapter(cmd.CommandText, conn);
You're only passing in the command text, which doesn't include the parameter. You want:
var adapter = new SqlCeDataAdapter(cmd, conn);
(I'd also suggest using a using statement for the command, and changing your method parameter names to follow .NET naming conventions. Oh, and you don't appear to be using the champion parameter...)
Oh, and you can add a parameter much more easily like this (also specifying the type, which is a good idea):
cmd.Parameters.Add("#Summoner", SqlDbType.NVarChar).Value = Summoner;

In DataAdapter Pass complete Command Object not only Command Text
var adapter = new SqlCeDataAdapter(cmd, conn);
or You can add parameter like this
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("#ID", SqlDbType.Int);
command.Parameters["#ID"].Value = customerID;
}
or you can use command.Parameters.AddWithValue also.

Related

using a variable in oledb command

What is the correct way to concatenate a variable when using the oledb command function in c# for a sql query. To apply some context im trying to make what a list box displays dependent on another selection made on a previous list box.This is what I've tried but doesn't work.
OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects
WHERE clients = " + (listBox1.SelectedItem.ToString()) , conn);
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
// Add items from the query into the listbox
listBox2.Items.Add(project[1].ToString());
}
String concatenation can lead to SQL Injection problems so you should not use it to build SQL. You should parameterize your query. So something like this...
using (OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects WHERE clients = ?", conn))
{
projects.Parameters.Add("?", OleDbType.VarChar).Value = listBox1.SelectedItem.ToString();
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
listBox2.Items.Add(project[1].ToString());
}
}
OleDbCommand Parameters are set in the order they are specified in the SQL, so if you have more than one you must do them in order.
using (OleDbCommand projects = new OleDbCommand("SELECT * FROM Client_projects WHERE clients = ? AND Date = ?", conn))
{
projects.Parameters.Add("?", OleDbType.VarChar).Value = listBox1.SelectedItem.ToString();
projects.Parameters.Add("?", OleDbType.Date).Value = DateTime.Today;
OleDbDataReader project = projects.ExecuteReader();
while (project.Read())
{
listBox2.Items.Add(project[1].ToString());
}
}
You are not using it but for other who might, SqlCommand uses named parameters...
SELECT * FROM Client_projects WHERE clients = #Clients
projects.Parameters.Add("#Clients", SqlDbType.VarChar).Value = listBox1.SelectedItem.ToString();

Input on a stored sql procedure using C#

In sql I normally execute my procedure using
exec dbo.usp_FCS 'TIMV','serial'
And I tried something somewhat the same in c# but it seems I got this wrong
using (SqlConnection connection = new SqlConnection("Data Source=;Initial Catalog=;User ID=;Password="))
{
using (SqlCommand cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya" + "'" + MachineName + " ','serial' " , connection))
{
try
{
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
}
catch (SqlException ex)
{
label6.Visible = true;
label6.Text = string.Format("Failed to Access Database!\r\n\r\nError: {0}", ex.Message);
return;
}
}
}
My question is,how can I give those 2 inputs 'TIMV' and 'serial' of my stored procedure using c#?
Edit:
I tried something like this:
using (SqlCommand cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya" , connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#p1", SqlDbType.VarChar).Value = MachineName;
cmd.Parameters.Add("#p2", SqlDbType.VarChar).Value = "serial";
try
{ my code...
And it is still not working
The most correct way to add a parameter to an SqlCommand is through the Add method that allows you to specify the datatype of the parameter and, in case of strings and decimals, the size and the precision of these values. In that way the Database Engine Optimizer can store your query for reuse and be a lot faster the second time you call it. In your case I would write
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#mname", SqlDbType.NVarChar, 20).Value = MachineName;
cmd.Parameters.Add("#serial", SqlDbType.NVarChar, 20).Value = "serial";
This assumes that your stored procedure receives two parameters named EXACTLY #mname and #serial, the type of the parameters is NVarChar and the length expected is 20 char. To give a more precise answer we need to see at least the first lines of the sp.
In your code above also the execution of the command is missing. Just creating the command does nothing until you execute it. Given the presence of an SqlDataAdapter I think you want to fill a DataSet or a DataTable and use this object as DataSource of your grid. Something like this
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
yourDataGrid.DataSource = dt;
And if this is an ASP.NET app, also the DataBind call
yourDataGrid.DataBind();
You use the Parameters collection of the SqlCommand class to send parameters to a stored procedure.
Suppose your parameter names are #p1 and #p2 (Please, for your sake, don't use names like this ever) - your c# code would look like this:
using (var cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya", connection))
{
cmd..CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#p1", SqlDbType.VarChar).Value = MachineName;
cmd.Parameters.Add("#21", SqlDbType.VarChar).Value = "serial";
try
{
// rest of your code goes here....
Note: use the SqlDbType value that fits the parameters data type.
Try this:
DataSet ds = new DataSet("dts");
using (SqlConnection conn = new SqlConnection
("Data Source=;Initial Catalog=;User ID=;Password="))
{
try
{
SqlCommand sqlComm = new SqlCommand("usp_FCS_GetUnitInfo_Takaya",conn);
sqlComm.Parameters.AddWithValue("#p1", MachineName);
sqlComm.Parameters.AddWithValue("#p2", "serial");
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
catch (Exception e)
{
label6.Visible = true;
label6.Text = string.Format
("Failed to Access Database!\r\n\r\nError: {0}", ex.Message);
return;
}

C# SQL Command parameter not working

I've done some trouble shooting by taking out the parameters and replacing them with text, and the only parameter that is not working is #seat and I can't figure out why.
allSeats is an array of custom controls. I've tried replacing the parameter contents with an actual string ie. "A1" and that still doesn't work. If I remove the #seat parameter and replace it with A1, it works, but I need to be able to set the column name dynamically.
myConnection.Open();
SqlCommand myCommand = new SqlCommand("UPDATE Events SET #seat = #truefalse WHERE Name = #name", myConnection);
SqlParameter param = new SqlParameter();
SqlParameter param2 = new SqlParameter();
SqlParameter param3 = new SqlParameter();
param.ParameterName = "#seat";
param2.ParameterName = "#truefalse";
param2.DbType = System.Data.DbType.Boolean;
param3.ParameterName = "#name";
param.Value = allSeats[i].Name;
param2.Value = allSeats[i].taken;
param3.Value = name;
myCommand.Parameters.Add(param);
myCommand.Parameters.Add(param2);
myCommand.Parameters.Add(param3);
myCommand.ExecuteNonQuery();
Any help is appreciated. If I need to post more relevant code please let me know and I shall add it.
In your
SET #seat = #truefalse
part, you try to parameterize your column name. You can't do that. You only can parameterize your values, not column name or table names.
You can use dynamic SQL for such a case but it is not recommended. Read
The Curse and Blessings of Dynamic SQL
SELECT * FROM #tablename
As a recommendation, use a white list such a case. I hope, there can only be a fixed set of possible correct values for the column name. Of course, this requires strong validation in your inputs part.
Agree with Soner. Change the string before you create the command
string cmdStr = string.Format("UPDATE Events SET {0} = #truefalse WHERE Name = #name", allSeats[i].Name)
Then
only use 2 parameters.
SqlCommand myCommand = new SqlCommand(cmdStr, myConnection);
SqlParameter param = new SqlParameter();
SqlParameter param2 = new SqlParameter();
etc.
cmd.parameter.addwithvalue("#param1", value1);
cmd.parameter.addwithvalue("#param2", value2);
use like this.
As Soner has mentioned, columns cannot be parameterized. This means you will either have to create dynamic queries, or create all the parameterized once at the startup, one query per column name.
this can be done in the following example:
private static Dictionary<string, SqlCommand> parameterizedCommands = new Dictionary<string,SqlCommand>();
public static void CreateparameterizedCommandsy(string[] colums)
{
parameterizedCommands = new Dictionary<string,SqlCommand>();
foreach (string colname in colums)
{
parameterizedCommands.Add(colname, CreateCommandForColumn(colname));
}
}
public static SqlCommand CreateCommandForColumn(string columnName)
{
SqlCommand myCommand = new SqlCommand(string.Format("UPDATE Events SET {0} = #truefalse WHERE Name = #name",columnName));
// the following statement creates the parameter in one go. Bit = boolean
myCommand.Parameters.Add("#truefalse", SqlDbType.Bit);
myCommand.Parameters.Add("#name", SqlDbType.Text);
return myCommand;
}
public int ExccuteColumnUpdate(string columnName, bool setToValue, string name, SqlConnection connection)
{
connection.Open();
try
{
SqlCommand command;
if (parameterizedCommands.TryGetValue(columnName, out command))
{
command.Connection = connection;
command.Parameters["#truefalse"].Value = setToValue;
command.Parameters["#name"].Value = name;
return command.ExecuteNonQuery();
}
}
finally
{
connection.Close();
}
return 0;
}

MySQL select query with parameter

I am trying to use MYSQL select query with c#.
Following query for searching "ID" is working fine:
conn = new MySqlConnection(cs);
conn.Open();
cmd = conn.CreateCommand();
cmd.CommandText = "select * from catalog_product_entity where entity_id = ?Id";
MySqlDataAdapter adp = new MySqlDataAdapter(cmd);
cmd.Parameters.Add("?Id", SqlDbType.Text).Value = ProductList[i].ProductId.ToString();
adp.Fill(MagentoProduct);
Now, I want to search exact string value in table. I am using following code and its giving empty result:
My Code:
conn = new MySqlConnection(cs);
conn.Open();
cmd = new MySqlCommand("select * from catalog_category_entity_varchar where value = #Value;", conn);
cmd.Parameters.AddWithValue("#Value", "Storybooks");
MySqlDataReader r = cmd.ExecuteReader();
while (r.Read())
{
log.WriteEntry(r.GetString("value"));
}
This is the problem:
where value = '?cname'
That's specifying ?cname as the literal value you're searching for - when you actually just want the parameter. Remove the quotes and it should be fine:
where value = ?cname
(You should use using statements for the connection and command, mind you...)
You could try SQL Reader
c = new MySqlCommand("select * from catalog_product_entity where column_nam = #Value;", conn);
c.Parameters.AddWithValue("#Value", your string);
MySqlDataReader r = c.ExecuteReader();
and then use Reader methods like reader.GetString("column_name"), ....

How to parameterise table name in ODBC query

I have an ODBC connection to a database and I would like the user to be able to view data within any table. As this is an ASP.net application I cannot trust that the table name sent doesn't also contain nasties. I have tried using a parameterised query but I always get an error saying that I "Must declare the table variable" - this appears to be an issue because it is the table name
string sql = "SELECT TOP 10 * FROM ? ";
OdbcCommand command = new OdbcCommand(sql, dbConnection);
command.Parameters.Add(new OdbcParameter("#table", tableName));
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(tableData);
What is the best method to achieve this in a secure way?
Use a stored procedure, it's the safest way.
Some hints:
You probably may also use the System.Data.SqlClient namespace objects
Enclose your connection, command and adapter objects initializations in using statements
Here's a simple example:
string sqlStoredProcedure = "SelectFromTable";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
using (OdbcCommand command = new OdbcCommand(sqlStoredProcedure, dbConnection))
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new OdbcParameter("#table", tableName));
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
Another way to go would be to retrieve all table names and validate the tableName string variable as an entry in the list, maybe using:
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
Here's a simple implementation based on your scenario:
string sql = "SELECT TOP 10 * FROM {0}";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
dbConnection.Open();
DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
var matches = tables.Select(String.Format("TABLE_NAME = '{0}'", tableName));
//check if table exists
if (matches.Count() > 0)
{
using (OdbcCommand command = new OdbcCommand(String.Format(sql, tableName), dbConnection))
{
using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
{
adapter.SelectCommand = command;
adapter.Fill(tableData);
}
}
}
else
{
//handle invalid value
}
}

Categories

Resources