How do i pass a stored procedure with parameters to a function.
I actually have a function to insert data into database..
im looking for a way where i could pass the SP with parameters to that
insert function so as to reuse the insert data code.
Put the call to the stored procedure in a method and call this method from anywhere you want to call it. Pass parameters (strings, ints, doubles, ...) to this method and put these values in the stored procedure's parameters.
This way you keep all the SP code in one place.
public class CustomerProvider
{
public int UpdateCustomer(int id, string name, string address)
{
using(connection = new
SqlConnection("Server=localhost;DataBase=Northwind;Integrated Security=SSPI"))
{
connection.Open();
var command = new SQLCommand("csp_updatecustomer", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(
new SqlParameter("#CustomerID", id));
command.Parameters.Add(
new SqlParameter("#CustomerName", name));
command.Parameters.Add(
new SqlParameter("#CustomerAddress", address));
var result = command.ExecuteNonQuery();
return result;
}
}
}
Related
I am building a recursive function in C# to call a set of stored procedures (I do not want to build one calling function for each stored procedure).
One of the parameters is a uniqueidentifier. However, if I send a parameter using the wrong type (a string for example), I get an exception:
Error converting data type nvarchar to uniqueidentifier
How can I check if the parameter to be sent to the stored procedure is a DbType.Guid ?
This is my calling function, and if the checking task could be done PRIOR to calling the stored procedure, this would be the best solution:
public SqlDataReader GetDataFromDB(string Cmdtext, CommandType CmdType)
{
_conString = WebConfigurationManager.ConnectionStrings["db_ConnectionString"].ConnectionString;
// Create Connection
SqlConnection con = new SqlConnection(_conString);
// Create Command
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = Cmdtext;
cmd.CommandType = CmdType;
//// Create ADO.NET parameters
cmd.Parameters.AddWithValue("#User", _User);
if (Cmdtext == "SpecificStoredProcedure")
{
cmd.Parameters.AddWithValue("#mGUID", _mGUID);
}
//// Return DataReader
con.Open();
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
Use Guid.TryParse , Guid.Parse
create a helper method where you create a new Guid with the string,
return true if success , catch the exception and return false if
exception
try
{
Guid guid = new Guid(data)
return true;
}
catch(Exception)
{
return false;
}
I have a stored procedure created with a static variable (#Location).
Im trying to create a C# app that will pass the LocationID parameter to the stored procedure. The parameters will need to be passed TWICE (Location1 and Location2). So far all I have is the following code, and I'm not sure how to loop it, or if its written properly?
using (Conn)
{
SqlCommand cmd = new SqlCommand("[dbo].[sp_EXAMPLESPROC]",Conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter LocationParam = cmd.Parameters.AddWithValu("#LocationID", "1");
LocationParam.SqlDbType = SqlDbType.Structured;
Let's say you put your code into a method called StoreLocation(). You'd make it take a parameter `locationId' (is it really a string like you have?) like so:
private void StoreLocation(string locationId)
{
using (Conn)
{
SqlCommand cmd = new SqlCommand("[dbo].[sp_EXAMPLESPROC]",Conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter LocationParam = cmd.Parameters.AddWithValue("#LocationID", locationId);
LocationParam.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery(); // Or however your sproc works.
}
}
Then you just call it twice or use a loop or whatever you want:
private void SomeCallerMethod()
{
// Whatever other code you have.
StoreLocation("1");
StoreLocation("2");
// More other code.
}
add LocationID1 and LocationID2 parameters to stored procedures and then
do like this
cmd.Parameters.Add(#LocationID1", SqlDbType.VarChar).Value = "1";
cmd.Parameters.Add(#LocationID2", SqlDbType.VarChar).Value = "2";
this should work
I have a web service in C#, I use it to consults from tables, but I want to create a WebMethod to call a stored procedure and get back multiples output parameters. I can execute it with output parameters, it doesn't work when I try to call it whit outputs parameters.
This is a sample, I want to get back more that 2 parameters.
Stored procedure:
CREATE OR REPLACE PROCEDURE O_CAPEREZ.GIO_SP (
VNOMBRE IN VARCHAR2,
SALUDO OUT VARCHAR2 )
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (vNOMBRE);
SALUDO:= ('Hello: ' || vNOMBRE);
END;
And this is my code in the web service, when I execute it using output variables I get this error
[HYC00] [Oracle][ODBC]Optional feature not implemented
C# code:
[WebMethod]
public string AP_Data(string curp)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (OdbcConnection con = new OdbcConnection(constr))
{
OdbcCommand cmd = new OdbcCommand("{CALL GIO_SP(?,?)}", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#vNOMBRE", (curp));
cmd.Parameters.Add("#vNOMBRE", OdbcType.VarChar, 18);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Parameters["#SALUDO"].Direction = ParameterDirection.ReturnValue;
cmd.Connection.Close();
string ret = Convert.ToString(cmd.Parameters["#SALUDO"].Value);
return ret;
}
}
You have to add the parameter to the list even if you're not going to set a value there:
cmd.Parameters.Add("#SALUDO", OdbcType.VarChar, 18).Direction = ParameterDirection.Output;
I don't know the the Oracle flavor is different, but in SQL I use ParameterDirection.ReturnValue rather than ParameterDirection.Output.
here's how i do it in MS SQL server 2008 But notice the data type and the lenth of the variables your create must be the same in your table
the stored proc create code
USE DATABASE DATABASE_NAME
GO
CREATE PROC SP_METHOD
#ID_CATIGORY INT,
#NAME VARCHAR (50),
#DESCRIPTION VARCHAR (50)
AS
INSERT INTO TABLE_NAME
([ID_CAT]
,[NAME_PRODUCT]
,[DESC_PRODUCT]
)
VALUES
( #ID_CATIGORY
,#NAME
,#DESCRIPTION )
GO
in the c# code
// Create SqlConnection
SqlConnection conn= new SqlConnection(#"Server=server_name;
DataBase=your_data_base_name;Integrated Security=false;User
Id=user_id;Password=password");
// Open the Connection
if (sqlconnection.State != ConnectionState.Open)
{
conn= .Open();
}
// execute stored_procedure method don't change this
public void ExecuteCommand(string stored_procedure, SqlParameter[] param)
{
SqlCommand sqlcomd = new SqlCommand();
sqlcomd.CommandType = CommandType.StoredProcedure;
sqlcomd.CommandText = stored_procedure;
sqlcomd.Connection = sqlconnection;
if (param !=null)
{
sqlcomd.Parameters.AddRange(param);
}
sqlcomd.ExecuteNonQuery();
}
// close connection method
public void close_conn()
{
if (sqlconnection.State == ConnectionState.Open)
{
sqlconnection.Close();
}
}
// execute and retrieving data Method
public void Add_product(int ID_cat ,string Name_Product,string
Des_Product)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("#ID_CAT", SqlDbType.Int);
param[0].Value = ID_cat;
param[1] = new SqlParameter("#NAME_PRODUCT", SqlDbType.VarChar, 50);
param[1].Value = Name_Product;
param[2] = new SqlParameter("#DESC_PRODUCT", SqlDbType.VarChar, 50);
param[2].Value = Des_Product;
ExecuteCommand("StoredProcedure_name", param);
close_conn();
}
and finally you can call this function
Add_product(Convert.ToInt32(ComboBox.SelectedValue),txt_name.Text,
txt_desc.Text);
if there is any part you don't understand lemme know
I've seen many ways to accomplish this.
One way is to Pipe Delimit your select statement in your stored procedure and then use "Value1|Value2".Split('|')[0] to get Value1.
You could also return a table instead of using multiple parameters
DataTable table = new DataTable();
DataAdapter adapter = new DataAdapter(cmd);
adapter.fill(table);
return table.Rows[0]["Greeting"] + table.Rows[0]["Name"];
In the second example you can return as many 'Parameters' as you want, but you will have to assign them to their rightful spots later in your code.
I've also seen an XML way to do this same feature but I won't provide the code here since I don't personally think it is a very good way to do it. The way I've seen done was adding a bunch of XML attributes to a parent tag, and then coming back later and finding the value of each tag later in the code.
In MYSQL it would go like this
CREATE PROCEDURE O_CAPEREZ.GIO_SP (
#vNOMBRE VARCHAR(50))
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (#vNOMBRE);
select 'Hola' as Greeting, #vNOMBRE as Name
END
Also note what Marc_s commented
You need to set the .Direction of the parameter BEFORE making the call to .ExecuteNonQuery()
I'm trying something new (for me, at least) and, rather than having specific functions for calling individual stored procedures (1-to-1 ratio of data access functions to stored procedures), I'm trying to write generalized functions that are passed a stored procedure name, as well as string arrays of parameter names and parameter values as arguments.
For example:
public DataTable CallQuery(string spName, string[] paramNames, string[] paramValues, string connString)
{
DataTable dt = new DataTable();
SqlConnection conn = new SqlConnection(connString);
try
{
//create a command and assign it to the passed stored procedure name
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn; // new SqlConnection(connString); ;
cmd.CommandText = spName;
//add any and all parameters to the command
for(int i = 0; i < paramNames.Length; i++)
{
SqlParameter temp = new SqlParameter(paramNames[i], paramValues[i]);
cmd.Parameters.Add(temp);
//cmd.Parameters.AddWithValue(paramNames[i], paramValues[i]);
}
//get the data and return it
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
return dt;
}
catch (Exception)
{
return dt;
}
}
Unfortunately, for some reason, when I call this function with parameter values (i.e. paramNames[0] = "#Provider" and paramValues[0] = "AT&T") and make the database call, I catch an exception saying that the stored procedure was expecting the parameter #Provider.
I've stepped through and verified that the parameters are being added with their values, but I'm still getting the same exception. Am I missing something simple here?
The reason I'm passing in the string arrays is because there could be anywhere from 0 to 5 parameters per stored procedure (so far...).
Try specifying a type for your parameters. However, the most important thing is make sure you do:
cmd.CommandType = CommandType.StoredProcedure;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL Server & .net support calling a stored procedure with param's values wihout providing param's names?
I want to call a command.ExecuteReader() of type Stored Procedure, however I do not want the parameter names that I pass to be identical to the ones in the SP. Below is a sample of what I'm trying to do
SP:
ALTER PROCEDURE SPName
#Id nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM TableName
WHERE ColumnName = #Id
END
GO
Code:
using (SqlCommand command = new SqlCommand(spName, connection) { CommandType = CommandType.StoredProcedure })
{
command.parameters.Add(new SqlParameter(*paramaeter name*, sqlDbType.nvarchar){ Value = "SomeValue"};
}
If you want a generic style function, without needing an extra round-trip, and you're happy to use reflection you could use something like this.
// Return an array of SqlParameter's by using reflection on ParamObject
private static SqlParameter[] GetParametersFromObject( object ParamObject )
{
var Params = new List<SqlParameter>();
foreach( var PropInfo in ParamObject.GetType().GetProperties() )
{
Params.Add( new SqlParameter( PropInfo.Name, PropInfo.GetValue( ParamObject, null ) ) );
}
return Params.ToArray();
}
public static void ExecuteSP( SqlConnection Connection, string SPName, object ParamObject )
{
using( var Command = new SqlCommand() )
{
Command.Connection = Connection;
Command.CommandType = CommandType.StoredProcedure;
Command.CommandText = SPName;
Command.Parameters.AddRange( GetParametersFromObject( ParamObject ) );
// Command.ExecuteReader()...
}
}
This uses reflection to get the property names and values out of the anonymous object to populate the SqlCommand. This can be used as such;
ExecuteSP( Conn, "GetStuff", new { Id = 7, Name = "Test" } );
This way ExecuteSP is 'generic' and you pick the parameter names and values when you call ExecuteSP.
Simple fact - you ultimately have to use the correct parameter name when calling a stored procedure because SQL server binds parameters by name (even when you use EXEC to call an SP without using named parameters, the parser binds them by name from left to right).
So if you want to use a different name you will need to introduce an intermediate layer between your SqlCommand and the target SP.
But if you just want to not care about the name and have it automatically discovered - then you can use the technique mentioned by Conrad Frix in his accepted answer on SQL Server & .net support calling a stored procedure with param's values wihout providing param's names? - which is why I've marked as a duplicate, because it is ultimately what you want to do, even if the reasons are different.
For SqlServer there is a DeriveParameters method that takes a command object and queries the database for the parameters (names and types) of the requested stored procedure.
You can then iterate over them and supply values.
Note: this means an extra trip to the database, so if you need this often, you might want to cache the results.
The method below allows you to write generic code for calling stored procedures, but also gives you the flexibility to perform specific actions for each different stored procedure
public delegate void SqlCOmmandDelegate(SqlCommand command);
public class Dal
{
public void ExecuteStoredProcedure(string procedureName,
SqlCommandDelgate commandDelegate)
{
using (SqlConnection connection = new SqlConnection())
{
connection.ConnectionString = GetConnectionString();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = procedureName;
connection.Open();
commandDelegate(command);
}
}
}
}
class UsesDal
{
public CallFirstProcedure(int value)
{
string userName;
ExecuteStoredProcedure("FIRST_PROCEDURE",
delegate(SqlCommand command)
{
command.Parameters.Add("UserID", value);
command.ExecuteReader();
//Do stuff with results e.g.
username = command.Parameters.Parameters["UserName"].ToString();
}
}
public CallOtherProcedure(string value)
{
int id;
ExecuteStoredProcedure("OTHER_PROCEDURE",
delegate(SqlCommand command)
{
command.Parameters.Add("ParameterName", value);
id = command.ExecuteScalar();
}
}
}