C# - Generalized SQL Server stored procedure calls - c#

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;

Related

How to validate a DbType.Guid as a Valid Parameter before calling a stored procedure?

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;
}

Passing parameter to SPROC that returns location specifc data?

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

How can I get multiple output parameters from a stored procedure in a web service in C#?

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()

Pass a parameter to a stored procedure in AS400 to match IN keywork

I am trying to pass as parameter to a stored procedure as string that will match the IN syntax.
I defined the parameter as CHARACTER and if I am writing the following it works:
MPROMY IN ( '2','3' )
MPROMY is the column in the database table.
I am trying to replace the values with the parameter:
MPROMY IN ( PRIORDAYS )
PRIORDAYS is the parameter passed in.
Here is my code in C#:
var daysIn = "'2','3'";
return CallStoredProcedure(string.Format("CALL SPORDCMP('{0}')", daysIn));
I am getting the following error:
ERROR [42000] [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0104 - Token 1 was not valid. Valid tokens: ) ,.
What is the correct syntax to pass a parameter in order to work with IN keyword?
This is how I've done it. In my case I am passing a store number (will not be hard coded when in production).
I build the command. Tell it the parms. Execute the stored procedure.
using IBM.Data.DB2.iSeries;
//Create a command object
cmd.Transaction = trans;
cmd.CommandText = "libraryname.storedprocedurename";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
ItemStoreNumber and ItemDesc are described in the model.
// Build the Stored Procedure Paramaters - Build Input Value
iDB2VarChar stNumber = "0001"; //Get from store later
iDB2Parameter parm = cmd.Parameters.Add("#ItemStoreNumber",
iDB2DbType.iDB2VarChar);
cmd.Parameters["#ItemStoreNumber"].Direction =
parameterDirection.Input;
cmd.Parameters["#ItemStoreNumber"].Value = stNumber;
DataTable dt = new DataTable();
iDB2DataAdapter da = new iDB2DataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
StoreItem storeitem = new StoreItem();
storeitem.ItemStoreNumber = (String)
row["RSTORE"].ToString();
storeitem.ItemDesc = (String) row["IDESC"].ToString();
storeitem.ItemUpc = (String)row["RUPC"].ToString();
storeitem.ItemUom = (String)row["ISUNIT"].ToString();
storeitem.ItemRpack = (String)row["RCPACK"].ToString();
storeitem.ItemRetailPrice =
Convert.ToDecimal(row["RCRETAILP"].ToString());
myStoreItems.Add(storeitem);
}
return myStoreItems;

Passing Parameters to SQL Server 2008

I am trying to pass parameters to my stored procedure. They are like this
#p_latitude='',#p_longitude='',#p_miles='',#p_searchtext='',#p_maptownid=182,#p_regionid=0
From code I am passing the parameters like
cmd.Parameters.Add("#p_latitude", SqlDbType.NVarChar).Value="''";
cmd.Parameters.Add("#p_longitude", SqlDbType.NVarChar).Value="''";
cmd.Parameters.AddWithValue("#p_miles",0);
cmd.Parameters.Add("#p_searchtext",SqlDbType.NVarChar).Value="''";
cmd.Parameters.AddWithValue("#p_maptownid",maptownid);
cmd.Parameters.AddWithValue("#p_regionid",0);
I'm getting an error cannot convert navarchar to float.
I tried in different ways sending null, string.empty. But couln't find it.
Empty strings should be passed as "" not "''". The apostrophes (') will be passed in as the string value and not as string delimiters.
The error message says you have a float column that you pass a nvarchar. I suspect that the #p_latitude and #p_longtitude params is the problem. Try to set the value directly as DBNull.Value.
I'm guessing that latitude, longitude and miles are floating point numbers. If so, you need to pass them as such:
cmd.Parameters.AddWithValue("#p_latitude", 0.0);
cmd.Parameters.AddWithValue("#p_longitude", 0.0);
cmd.Parameters.AddWithValue("#p_miles", 0.0);
Try using DbType.String instead of SqlDbType.NVarChar
Well actually, this is how I do it (they were all in different layers so I suggest you to do the same):
List<SqlParameter> parameters = new List<SqlParameter> { };
string status = "dummystatus";
string date = Datetime.Now;
parameters.Add(new SqlParameter("#Status", status));
parameters.Add(new SqlParameter("#date", date));
SqlCommand cmd = new SqlCommand();
command.Connection = connection;
//set the command text (stored procedure name or SQL statement)
command.CommandText = commandText;
command.CommandType = commandType;
foreach (SqlParameter p in parameters)
{
command.Parameters.Add(p);
}
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
//fill the DataSet using default values for DataTable names, etc.
da.Fill(ds);
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();

Categories

Resources