How can I execute a stored procedure that takes in parameters without having to specify the prameters name? The name of the parameter in the stored procedure may change from CustomerID to CustID so I don't want to have to keep changing my code.
Rather than doing what is provided below where you specify the parameter name -
command.Parameters.Add("#dtStart", SqlDbType.DateTime);
command.Parameters["#dtStart"].Value = startDate;
command.Parameters.Add("#CustomerID", SqlDbType.NChar);
command.Parameters["#CustomerID"].Value = customerID;
I am looking to do something like this -
command.Parameters.Add(startDate, customerID);
The name of the parameter in the stored procedure may change from CustomerID to CustID
Slap the person who does that.
Parameter names are your reliable way of identifying a parameter. The other option is sequence, seems a lot more flaky.
I don't think you can create a SqlParameter object without specifying its name. However, you should be able to use the DeriveParameters method (see MSDN) to get a collection of parameters with the names automatically retreived from the SQL server.
You can find an example here. It looks roughly like this:
SqlCommand command = // create a command for calling the stored procedure
SqlCommandBuilder.DeriveParameters(command);
// Now you can set values of parameters in a loop
for(int i = 0; i < command.Parameters.Length; i++) {
var parameter = command.Parameters[i]
// Set value of ith parameter
}
You can create a nameless SQL parameter if you force its name to null or empty after it's been added to the Parameters collection, something like this:
var par = cmd.CreateParameter();
par.Value = myValue;
cmd.Parameters.Add(par); // this will change the name to "ParameterX"
par.ParameterName = null;
Use Parameter Discovery, scroll down on: http://msdn.microsoft.com/en-us/library/ff664692(PandP.50).aspx
Using Unnamed parameters is only possible with OdbcCommand and OleDbCommand object parameters.
You could use SQL's exec, which does not ask for parameter names:
command.CommandText = string.Format(
"exec dbo.YourProcedure {0}, '{1}'",
intParameter,
stringParameter.Replace("'","''")
);
command.ExecuteNonQuery();
If your parameter source is untrustworthy, be sure to escape single quotes in string parameters. It's done for stringParameter in the snippet above.
Related
I can do:
await _sensorContext.Database.ExecuteSqlRawAsync("call testproc()");
And I can do:
System.Data.Common.DbConnection? c = _sensorContext.Database.GetDbConnection();
c.Open();
var cmd = c.CreateCommand();
cmd.CommandText = "call dewpointaverage('{\"70B3D52DD50003AC\",\"70B3D52DD5000452\"}'::varchar[])";
cmd.ExecuteNonQuery();
Which works, but I cannot figure out how to build and pass the parameter array in either (though preferably the first) approach.
There is no returned result set, the proc uses the parameters to calculate values and populate a table.
How can I pass the parameter array into either of these code examples?
await this._sensorContext.Database
.ExecuteSqlRawAsync("EXEC StoredProcedureName #FirstParameter, #SecondParameter",
new SqlParameter("FirstParameter", "ParameterValue"),
new SqlParameter("SecondParameter", "SecondParameterValue"));
To pass an array of elements, you can create an UserDataTable and follow this guide to give a list to your stored procedure.
Table-valued parameters
This is my manual query work in SQL:
SELECT * FROM Accounts where Phone in ('05763671278','05763271578','04763125578')
how can I get parameter like this to stored procedure from csharp?
I have a phones array in C#. I get this array from parameters from a view (multi check box select). This is my view:
<td><input type="checkbox" class="CheckboxClass" value="'#item.Phones'"/></td>
This is my controller action:
public ActionResult SendSMSOrMail(string[] values){
// this give "'05763671278','05763271578','04763125578'"
string numbers = string.Join(",", values);
// ...
utility.cmd.Parameters.Add("#numbers", numbers);
// ...
}
But the result is null. What is wrong? I want to get result of all records which contain these phones.
There are several ways to do this. The first is to create your array as a string of text, separated by commas or semicolons or some other separator, then in the SQL you would parse that string. That's pretty simple and straight forward, but does not scale very well and there is a limit to the max character length of a parameter.
A second choice is to use an XML parameter. Example here:
https://stackoverflow.com/a/1069388/61164
A third choice is to use a Table parameter, which be passed as a .NET collection.
I don't have an example of that handy. I've done it before, but that should give you enough info to search for yourself.
I suggest you use a table valued parameter
CREATE TYPE PhonesTableType AS TABLE
(
Phone VARCHAR(12)
)
GO
Then you should declare (at the creation script) that you stored procedure expects a parameter of this type:
CREATE PROCEDURE dbo.your_stored_procedure_name
(
#PhonesTableType PhonesTableType READONLY
)
....
SELECT A.*
FROM Accounts AS A
INNER JOIN #PhonesTableType AS P
ON A.Phone = P.Phone
Then at the C# code you should create a DataTable with one column and pass there the values you have mentioned. Last you should pass this a parameter to your stored procedure.
var phonesDataTable = new DataTable("Phones");
phonesDataTable.Columns.Add("Phone", typeof(string));
foreach(var phone in phones) // phones is the values
{
phonesDataTable.Rows.Add(phone);
}
Then if we suppose that you have named command the command that you would ask to be executed, before executing it you should add the above as a parameter:
var sqlParameter = new SqlParameter
{
ParameterName = "#PhonesTableType",
SqlDbType = SqlDbType.Structured,
Value = phonesDataTable
};
command.Parameters.Add(sqlParameter);
I want to save formatted text into a table, and i use this nice rich text editor that outputs HTML. When I run it i get:
There was an error parsing the query. [ Token line number = 1,Token
line offset = 31,Token in error = < ]
My command looks like:
new SqlCeCommand("UPDATE Bio SET text = " + form["textbox"].Replace("\"", """) + " WHERE id = " + ViewBag.Id, conn)
But I guess it does not like <>, what do I need to replace? Do the same with the quote as with the <>? Any function that escapes it all?
See here for an example of passing the text you want to insert as a parameter:
http://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlcecommand.parameters(v=vs.100).aspx
As recommended by MattD - here is example code. Note that I did not actually run this, if there is a syntax issue, leave a note and I'll fix it. This should get you 99% of the way in any case.
Also note: it is ALWAYS a good idea to use parameters this way, rather than appending literal text into a sql query. This eliminates the possibility of a SQL injection error or hack, where someone might maliciously enter text that finishes your SQL and then adds their own SQL that will also get executed.
SqlCeCommand command = new SqlCeCommand("UPDATE Bio SET text = #htmlText WHERE id = #id", conn);
SqlCeParameter param;
// NOTE:
// For optimal performance, make sure you always set the parameter
// type and the maximum size - this is especially important for non-fixed
// types such as NVARCHAR or NTEXT; In case of named parameters,
// SqlCeParameter instances do not need to be added to the collection
// in the order specified in the query; If however you use ? as parameter
// specifiers, then you do need to add the parameters in the correct order
//
param = new SqlCeParameter("#id", SqlDbType.Int);
command.Parameters.Add(param);
param = new SqlCeParameter("#htmlText", SqlDbType.NVarChar, -1);
command.Prepare();
//Set the values and the length of the string parameter
command.Parameters[0].Value = ViewBag.Id;
command.Parameters[1].Value = form["textbox"];
command.Parameters[1].Size = form["textbox"].Length;
// Execute the SQL statement
//
command.ExecuteNonQuery();
Does anyone know how can I read the output variable from .net c#?
Example:
If I have the following stored proc which will return the output variables (#customer_id, #customer_name, #customer_address, #customer_age) instead of the select variable, how can I read the output variable with the following?
mySqlCommand.CommandText = "EXEC app_customers #name=" + sName.Text;
mySqlConnection.Open();
SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
while (mySqlDataReader.Read())
{
}
When the result is a single value (or if you're just interested in the first value in the first column), use the method ExecuteScalar.
It returns an object, simply cast it to the expected type.
int id = (int)mySqlCommand.ExecuteScalar();
Note: the way you're invoking a procedure is not the normal way to do it. Set the command to reference the stored procedure, then add appropriate parameters to the command.Parameters collection. Invoking the procedure using "exec ..." is not a best practice and may even leave you vulnerable. If you need more info on executing such a call, start here.
Edit:
If it is truly an output parameter you need to capture (I believe I misread your question), then the above paragraph is even more applicable. Consider this approach:
mySqlCommand.CommandText = "app_customers";
mySqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
mySqlCommand.Parameters.AddWithValue("#name", theValue);
var customerIdParam = mySqlCommand.Parameters.Add("#customer_id", System.Data.SqlDbType.Int);
customerIdParam.Direction = System.Data.ParameterDirection.Output;
// add more parameters, setting direction as appropriate
mySqlCommand.ExecuteNonQuery();
int customerId = (int)customerIdParam.Value;
// read additional outputs
I've written a piece of c# code which executes a stored procedure on an MS SQL box. I Create the SP like so:
SqlCommand command = new SqlCommand(creditLimitRequestSP, connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
I then create a set of parameters using the constructor for the parameters:
SqlParameter p1 = new SqlParameter(p1, p1Value);
vdnParam.Size = 7;
Some of my parameters are integers in which case I parse them like so:
int p4Value = 0;
bool parsedP4 = Int32.TryParse(p4AsAString, out p4Value);
SqlParameter p4;
if (parsedP4)
{
p4 = new SqlParameter("#p4", SqlDbType.Int, p4Value);
p4.Size = sizeof(Int32);
}
else
{
throw new InvalidFieldDataException("p4", p4AsString);
}
Then after I've parsed the parameters from a dictionary I add them like so:
command.Parameters.Add(p1);
command.Parameters.Add(p2);
command.Parameters.Add(p3);
command.Parameters.Add(p4);
command.Parameters.Add(p5);
command.Parameters.Add(p6);
When I execute the stored procedure I get an exception telling me is is expecting a parameter which I have added to the command. Why would it do this?
Initially I thought this might be because the parameters were being added in the wrong order but I changed them to match the order in the Stored procedure (event though it shouldn't matter as I'm using named parameters) and it didn't resolve anything.
The parameter in question does not have a default value in the SP, and it an integer value.
If the exception you get is telling that you are not adding a parameter, then it must be that you're not adding it. The parameters must match by name indeed (order doesn't matter), and all non-optional parameters must be present. Direction (Input, Output) must also be correctly set.
The exception message should tell you which parameter is not present, or has the wrong type.
There is no much to help you here, since there must be something at odd between what you believe you're passing and what you actually pass. You should monitor the RPC:Starting Event Class in the SQL Profiler and see exactly what are you passing.
I think I've found the answer...
p4 = new SqlParameter("#p4", SqlDbType.Int, p4Value);
The third Parameter is not the value it's the size of the param.
To set the value you need to call;
p4.Value = p4Value;
Going to test and will come back...