This question already has answers here:
Call a stored procedure with parameter in c#
(7 answers)
Closed 5 years ago.
I've got a stored procedure that runs just fine if I execute it on my server and if I build an execute statement with my parameters (e.g. string sql = "Exec Get_Data '" + St + " ' ...". However, as soon as I try:
string strQS = "Exec Get_Data #param1,#param2,#param3,#param4..."
using (SqlConnection conSQL = new SqlConnection(connectionString))
{
using (SqlCommand cmdSQL = new SqlCommand(strQS, conSQL))
{
conSQL.Open();
cmdSQL.Parameters.AddWithValue("#param1", SqlDbType.VarChar).Value = St;
cmdSQL.Parameters.AddWithValue("#param2", SqlDbType.VarChar).Value = Loc;
...
I get the following error:
Column name or number of supplied values does not match table definition.
Obviously if I can run it before I use a parametrized query I don't have anything wrong with my column names, but something with how my values are being treated. All my variables are of type string and the SQL Server is expecting all parameters to by of type varchar...Any ideas?
You need to change your command type to StoredProcedure.
And then drop the EXEC and all the parameters from your string.
cmdSQL.CommandType = CommandType.StoredProcedure;
string strQS = "Get_Data"
Related
This question already has answers here:
A table name as a variable
(10 answers)
Closed 1 year ago.
I am building a sql query string like this:
var sqlDailyDataForOption = #"select underlying_symbol, quote_date
FROM [#val6]
Later I add the command line parameters thus:
command.Parameters.AddWithValue("#val6", o.underlying_symbol + "_1545");
I get an exception when I try to execute the query string:
using (SqlDataReader reader = command.ExecuteReader())
{
- $exception {"Invalid object name '#val6'."} System.Data.SqlClient.SqlException
However, if I hardwire the value o.underlying_symbol + "_1545" it works fine.
Is it that command-parameters can't be dynamically created in a FROM ?
You would have to use dynamic SQL and safely inject the value of the dynamic object into the statement. I'm not a C# developer, but I suspect it'll look something like this:
var sqlDailyDataForOption = #"DECLARE #SQL nvarchar(MAX) = N'SELECT underlying_symbol, quote_date FROM dbo.' + QUOTENAME(#var6) + N';'; EXEC sys.sp_executesql #SQL;"
command.Parameters.Add("#Var6", SqlDbType.NVarChar, 128).Value = o.underlying_symbol + "_1545"
try this
var val16=o.underlying_symbol + "_1545";
var sqlDailyDataForOption = $"select underlying_symbol, quote_date FROM [{val16}]";
but please remember about possibility sql script injection attack in this case and check val16 for malicious words like delete.
This question already has answers here:
How to execute a stored procedure within C# program
(14 answers)
Call a stored procedure with parameter in c#
(7 answers)
Closed 5 years ago.
I'm trying to call a parameterized stored procedure from a console app. Here is the code:
var connection = new SqlConnection(connectionString);
var cmd = new SqlCommand("MyStoredProcedure", connection);
connection.Open();
cmd.Parameters.Add("#Email", SqlDbType.VarChar).Value = email;
cmd.Parameters.Add("#Account", SqlDbType.VarChar).Value = accountNumber;
cmd.Parameters.Add("#EmployeeId", SqlDbType.VarChar).Value = $"Prod-{empIdNumber}";
cmd.ExecuteNonQuery();
I get an exception returned that the stored procedure expects an #EmployeeId parameter which was not provided. I have double checked the spelling.
Can anyone tell me what I'm missing?
edit: I should add, that the stored procedure works fine when called directly.
This question already has answers here:
SQL : in clause in stored procedure:how to pass values
(8 answers)
Closed 7 years ago.
What I want to do :
Pass this parameter 'TV','OV','CK' as a single string into Stored Procedure (GetAllDataViaInQuery)
CREATE PROCEDURE GetAllDataViaInQuery #param varchar(240)
AS
BEGIN
SELECT TOP 100 [Model_No]
,[AppCode]
,[Model]
FROM [S_ModelMaster] where AppCode in (#param)
END
Then
I need to Pass parameter value via C# application as a single parameter.Because some time in values are may be vary.
Ex : string paramValue = "TV,OV,CK";
Then I wrote this C# code snippet.
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.Setting))
{
try
{
//hard coded parameter values
string paramValue = "TV,OV,CK";
con.Open();
DataSet ds = new DataSet();
SqlCommand com = new SqlCommand("GetAllDataViaInQuery", con);
com.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("#param", paramValue);
com.Parameters.Add(param);
SqlDataAdapter adp = new SqlDataAdapter(com);
adp.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
But this is not work yet.
Then I execute Stored Procedure manually with SSMS.
DECLARE #return_value int
EXEC #return_value = [application].[GetAllDataViaInQuery]
#param = N'TV,OV,CK'
SELECT 'Return Value' = #return_value
But it's NOT WORKED!
Then I try it in sql query
SELECT TOP 100 [Model_No]
,[AppCode]
,[Model]
FROM [S_ModelMaster] where AppCode in ('TV','OV','CK')
And it's work.So what is the correct way to pass parameter to IN query in C#?
The way i see around this is, Use table valued parameters and send parameter in datatable format from c#.
And in Stored procedures something like select * from TableName where AppCode in(select parameter from tvpTable)
This is similar
Table valued parameters
This question already has answers here:
How to use a variable for the database name in T-SQL?
(4 answers)
Closed 10 years ago.
I can't change the database file size with a C# query. For some reason I get an exception: "Incorrect syntax near '#databaseName'.
This is the code that executed the query:
command = connection.CreateCommand();
command.CommandText = #"
ALTER DATABASE #databaseName
MODIFY FILE
(NAME = #databaseFile, SIZE = #newSize)
";
dbParam = command.CreateParameter();
dbParam.ParameterName = "databaseFile";
dbParam.Value = dbFileName;
command.Parameters.Add(dbParam);
dbParam = command.CreateParameter();
dbParam.ParameterName = "newSize";
dbParam.Value = newSize;
command.Parameters.Add(dbParam);
dbParam = command.CreateParameter();
dbParam.ParameterName = "databaseName";
dbParam.Value = databaseName;
command.Parameters.Add(dbParam);
command.ExecuteNonQuery();
Now there might be several problems. Firstly the database is on a different machine so wouldn't the db file path be different?
Some things cannot be parameterized. That includes things like table and column names in DML, but includes most of DDL. It is not expecting, and cannot process, parameters in this scenario.
To check this; just run it in SSMS, declaring the variables ahead of time and giving them values. You will find the error message is the same. If it doesn't work in SSMS it is very unlikely to work from ADO.NET.
I have an SQL statement that I'm executing through OleDb, the statement is something like this:
INSERT INTO mytable (name, dept) VALUES (#name, #dept);
I'm adding parameters to the OleDbCommand like this:
OleDbCommand Command = new OleDbCommand();
Command.Connection = Connection;
OleDbParameter Parameter1 = new OleDbParameter();
Parameter1.OleDbType = OleDbType.VarChar;
Parameter1.ParamterName = "#name";
Parameter1.Value = "Bob";
OleDbParameter Parameter2 = new OleDbParameter();
Parameter2.OleDbType = OleDbType.VarChar;
Parameter2.ParamterName = "#dept";
Parameter2.Value = "ADept";
Command.Parameters.Add(Parameter1);
Command.Parameters.Add(Parameter2);
The problem I've got is, if I add the parameters to command the other way round, then the columns are populated with the wrong values (i.e. name is in the dept column and vice versa)
Command.Parameters.Add(Parameter2);
Command.Parameters.Add(Parameter1);
My question is, what is the point of the parameter names if parameters values are just inserted into the table in the order they are added command? The parameter names seems redundant?
The Problem is that OleDb (and Odbc too) does not support named parameters.
It only supports what's called positional parameters.
In other words: The name you give a parameter when adding it to the commands parameters list does not matter. It's only used internally by the OleDbCommand class so it can distinguish and reference the parameters.
What matters is the order in which you add the parameters to the list. It must be the same order as the parameters are referenced in the SQL statement via the question mark character (?).
But here is a solution that allows you to use named parameters in the SQL statement. It basically replaces all parameter references in the SQL statement with question marks and reorders the parameters list accordingly.
It works the same way for the OdbcCommand class, you just need to replace "OleDb" with "Odbc" in the code.
Use the code like this:
command.CommandText = "SELECT * FROM Contact WHERE FirstName = #FirstName";
command.Parameters.AddWithValue("#FirstName", "Mike");
command.ConvertNamedParametersToPositionalParameters();
And here is the code
public static class OleDbCommandExtensions
{
public static void ConvertNamedParametersToPositionalParameters(this OleDbCommand command)
{
//1. Find all occurrences of parameter references in the SQL statement (such as #MyParameter).
//2. Find the corresponding parameter in the commands parameters list.
//3. Add the found parameter to the newParameters list and replace the parameter reference in the SQL with a question mark (?).
//4. Replace the commands parameters list with the newParameters list.
var newParameters = new List<OleDbParameter>();
command.CommandText = Regex.Replace(command.CommandText, "(#\\w*)", match =>
{
var parameter = command.Parameters.OfType<OleDbParameter>().FirstOrDefault(a => a.ParameterName == match.Groups[1].Value);
if (parameter != null)
{
var parameterIndex = newParameters.Count;
var newParameter = command.CreateParameter();
newParameter.OleDbType = parameter.OleDbType;
newParameter.ParameterName = "#parameter" + parameterIndex.ToString();
newParameter.Value = parameter.Value;
newParameters.Add(newParameter);
}
return "?";
});
command.Parameters.Clear();
command.Parameters.AddRange(newParameters.ToArray());
}
}
Parameter NAMES are generic in the SQL support system (i.e. not OleDb specific). Pretty much ONLY OleDb / Odbc do NOT use them. They are there because OleDb is a specific implementation of the generic base classes.