I'm accessing a stored procedure and I'm trying to pass some parameters to it. I have the following loop that adds all parameters:
List<string> paramNames = new List<string> {
"#EmployeeId",
"#Location",
"#StartYear",
"#EndYear",
"#Department",
"#Title",
"#FileName"
};
List<string> paramValues = new List<string> {
EmployeeId,
Location,
StartYear,
EndYear,
Department,
Title,
FileName
};
// Add the input parameter and set its properties.
SqlParameter parameter;
for (int i = 0; i < paramNames.Count(); i++)
{
parameter = new SqlParameter();
parameter.ParameterName = paramNames[i];
parameter.Value = paramValues[i];
command.Parameters.Add(parameter);
}
the first parameter is "EmployeeId" and this value is coming from the method arguments. This parameter can either be a string value "All" or it can be an int value with the employee id.
-How do I pass its value to the stored procedure so it accepts a string or an int.
-And how do I tell it that if its "All" then I want all employees, otherwise if its a number, I want the employee with that number ID?
Most likely your stored procedure has a condition similar to
WHERE EMPLOYEE_ID = #EmployeeId
Change it to
WHERE #EmployeeId = 'All' OR EMPLOYEE_ID = #EmployeeId
This is a 'catch all' condition. If you pass 'All' - first part will be true and condition passes. Otherwise value of the parameter will be verified against table field
Instead of using "All" you could simply just use a value of -1 or 0 for EmployeeId and then check for 0 or -1 in your stored procedure to return all users in that scenario.
Related
I have a .NET 4.8 app that is calling a SQL Server stored procedure using SqlQuery (inside a DbContext). Most of the stored procedures take a couple of input parameters and return a number of rows, with a single output parameter giving the number of rows returned. These work fine.
I have one stored procedure that takes a single input, returns no rows, but has three output parameters. When I call this, I get no data returned and the output parameters appear to be unset (null).
PROCEDURE GetBob
#InVal INT,
#OutVal1 INT OUTPUT,
#OutVal2 NVARCHAR(30) OUTPUT,
#OutRows INT OUTPUT
AS
BEGIN
SELECT #OutVal1 = 1
SELECT #OutVal2 = "bob"
SELECT #OutRows = 1
END
When I execute this in SQL Server, I get 1, bob and 1 respectively.
SqlParameter param1 = new SqlParameter() {
Direction = System.Data.ParameterDirection.Input,
ParameterName = "#InVal",
SqlDbType = System.Data.SqlDbType.Int,
Value = 1
};
SqlParameter param2 = new SqlParameter() {
Direction = System.Data.ParameterDirection.Output,
ParameterName = "#OutVal1",
SqlDbType = System.Data.SqlDbType.Int,
};
// etc. for the last two params.
And my call is defined as follows:
var x = Database.SqlQuery<ab>("GetBob #InVal, #OutVal1, #OutVal2, #OutRows", param1, param2, param3, param4).ToList();
For this example, ab is a class that contains a property for each output parameter.
Does anyone have any ideas why it is not picking up the output parameters. I would expect x to be empty as no actual rows are returned, but the output parameters should be populated.
I've been trying to pass 2 field data type to oracle procedure from c#. I can do it for 1 field like below;
oracle:
TYPE my_array IS TABLE OF VARCHAR2(40) INDEX BY BINARY_INTEGER;
PROCEDURE insert_question(test IN my_array) IS
BEGIN
--something
END;
C#:
command.Parameters.Add(new OracleParameter("test", OracleDbType.Varchar2)
{
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
UdtTypeName = "my_array",
Value = data_list.ToArray(),
Size = data_list.Count,
Direction = ParameterDirection.Input
});
It is ok until here. Now, i need to pass 2 field list to oracle stored procedure like;
number
text
I created a new type named for_questions;
TYPE fields IS RECORD
(
num NUMBER,
text VARCHAR2(1000)
);
TYPE for_questions IS TABLE OF fields INDEX BY BINARY_INTEGER;
and i have a list at c# with 2 field. I've tryed this code for pass data to oracle procedure as parameter;
command.Parameters.Add(new OracleParameter("fixed", OracleDbType.Varchar2)
{
CollectionType = OracleCollectionType.PLSQLAssociativeArray,
UdtTypeName = "for_questions",
Value = fixed_q.ToArray(),
Size = fixed_q.Count,
Direction = ParameterDirection.Input
});
But it doesn't work as expected. So i need some help. How can i pass a 2 field list/array to oracle stored procedure as parameter?
Thanks in advance.
NOTE:Adviced question doesn't helpfull for me because it's on java. My problem is: I can't pass multiple field type as a parameter in c#.
I have an application that gets a grade name and pass parameter from a stored procedure. This works except for the case where there is no grade name in my grade table. Do I need to modify the parameters to make them accept null and/or do I need to modify the place where I assign those parameters to the C# parameters so I can make it accept a value or null?
I have this stored procedure. It's been shortened for this question:
CREATE PROCEDURE sp_mark_test
#GradeName NVARCHAR(10) OUTPUT,
#GradePass BIT OUTPUT
AS
BEGIN
-- Example only, real code does not hard code in 99
SELECT top 1 #GradeName = Grade.Name, #GradePass = Grade.Pass
FROM AdminTest
WHERE TestId = 99
END
Here is my C# code:
var sql = #"dbo.sp_mark_test #GradeName OUT,
#GradePass OUT";
SqlParameter[] parameters = new SqlParameter[] {
new SqlParameter("#GradeName", SqlDbType.NVarChar) { Direction = ParameterDirection.Output,Size = 10 },
new SqlParameter("#GradePass", SqlDbType.Bit) { Direction = ParameterDirection.Output }
};
await db.Database.ExecuteSqlCommandAsync(sql, parameters);
var GradeName = (string)parameters[1].Value;
var GradePass = (Boolean)parameters[2].Value;
As requested, and this is just a quick answer, look into the use of DBNull such as
cmd.Parameters.AddWithValue("#closeDate", DBNull.Value);
or use it for comparisons.
MSDN Page on the DBNull class. A code snippet from it is below:
if (! DBNull.Value.Equals(row[fieldName]))
return (string) row[fieldName] + " ";
else
return String.Empty;
I am passing a datatable from Code to stored procedure in this way.
DataTable table = CommonFunctions.ToDataTable(request);
object[] spParams = new object[1];
spParams[0] = table;
DbCommand dbCommand =
db.GetStoredProcCommand("OS_UpdateOrgStructureDetails", spParams);
I am trying to access this parameter in stored proc.
CratePROCEDURE OS_UpdateOrgUnits
#table OS_RenameNodeTable READONLY
AS
BEGIN
UPDATE OrgUnit
SET DetailName = ut.NewValue
FROM #table ut
INNER JOIN OrgUnit ou ON ou.OrgUnitID = ut.OrgUnitID
END
But when the call is made to stored procedure it throws an error.
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol
stream is incorrect. Table-valued parameter 1 ("#table"), row 0, column 0:
Data type 0xF3 (user-defined table type) has a non-zero length database name
specified. Database name is not allowed with a table-valued parameter, only
schema name and type name are valid.
Not able to resolve the error.
Because of a bug in the SqlCommandBuilder.DeriveParameters method, the TypeName property of the SqlParameter object for the table valued parameter contains the database name (see http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommandbuilder.deriveparameters.aspx, the comment "Table valued parameters not typed correctly").
The fix this you can add this general purpose code right after creating the command:
foreach (SqlParameter parameter in dbCommand.Parameters)
{
if (parameter.SqlDbType != SqlDbType.Structured)
{
continue;
}
string name = parameter.TypeName;
int index = name.IndexOf(".");
if (index == -1)
{
continue;
}
name = name.Substring(index + 1);
if (name.Contains("."))
{
parameter.TypeName = name;
}
}
If you only have one or two table parameters, you don't have to loop through all the parameters. I wrote a function instead and passed that parameter to that function so that it would fix the typename.
This is the function:
Private Sub SetTypeNameForTableParameter(ByRef parameter As System.Data.SqlClient.SqlParameter)
If parameter.SqlDbType = SqlDbType.Structured Then
Dim name As String = parameter.TypeName
Dim index As Integer = name.IndexOf(".")
If index <> -1 Then
name = name.Substring(index + 1)
If name.Contains(".") Then
parameter.TypeName = name
End If
End If
End If
End Sub
This is the piece of code where I'm making the call to the database:
'Get Parameters in stored proc
Dim cmd As System.Data.Common.DbCommand = db.GetStoredProcCommand("MyStoredProc")
db.DiscoverParameters(cmd)
'The first parameter is the return value. Remove it.
Dim returnValueParam As Data.Common.DbParameter = cmd.Parameters(0)
cmd.Parameters.Remove(returnValueParam)
'Set type name for every table parameter
SetTypeNameForTableParameter(cmd.Parameters(1))
'Assign values to the parameters
cmd.Parameters(0).Value = id
cmd.Parameters(1).Value = mydatatable
'Execute the command
db.ExecuteNonQuery(cmd)
CREATE PROCEDURE [dbo].[Code]
#intEpmName NUMERIC,
#strFailedEMPID VARCHAR(1000) output
AS
DECLARE
#FailedCodes VARCHAR(1000)
BEGIN
----
my logic where i need return the value
SET #strFailedEMPID = #FailedCodes
-----
END
In the stored procedure above, I can send the value as "0" to #strFailedEMPID then to my procedure. However, when I return the value from my procedure, then to the same variable #strFailedEMPID I am sending the value as such:
lsqlParam = new SqlParameter("#strFailedEMPID ", SqlDbType.VarChar);
lsqlParam.Value = "0";
lsqlParam.Direction = ParameterDirection.ReturnValue;
lsqlCmd.Parameters.Add(lsqlParam);
Can anyone help with the correct syntax to get the return value from the procedure?
It's because you are defining the parameter in .NET as a ReturnValue which would actually equate to the scenario where you use RETURN within the stored procedure to return an integer (which you're not doing).
Instead, you need to define the #strFailedEMPID parameter as ParameterDirection.Output within your .NET code. If you want to pass a value in AND receive one out through the parameter, use ParameterDirection.InputOutput.
After executing the sproc, you then just:
string value = lsqlCmd.Parameters["#strFailedEMPID"].value;
So....
lsqlParam = new SqlParameter("#strFailedEMPID ", SqlDbType.VarChar);
lsqlParam.Value = "0";
lsqlParam.Direction = ParameterDirection.InputOutput;
lsqlCmd.Parameters.Add(lsqlParam);
lsqlCmd.ExecuteNonQuery();
string value = lsqlCmd.Parameters["#strFailedEMPID"].value;