I have a table that has a field, "IsActive," that indicates whether a record has been "deleted" or not.
Currently, I retrieve this info like so:
public DataTable GetContractors(bool IsActive)
{
SqlParameter paramIsActive = new SqlParameter("#IsActive", SqlDbType.Bit);
paramIsActive.Value = IsActive;
DataSet ds = this.SQLDataAccess.ExecSProcReturnDataset(this.AppConfig.ConnectString, "p_selContractors", paramIsActive);
return ds.Tables[0];
}
The code for my DAL and stored procedure is irrelevant, so I'll omit that for now.
Here is my question: this code works fine if I want to return records that ARE active or ARE NOT active... but, how would I modify this to return ALL records (active AND inactive)?
Right now, I have two methods and two stored procs (one with the IsActive parameter and the other without the param), but I know there must be an easier way.
Any suggestions?
Pass a NULL (assign DBNull.Value to the parameter) and modify your stored procedure to check for that and not care what type of record it is in that circumstance. Some thing like:
.... WHERE MyTable.IsActive = COALESCE(#IsActive, MyTable.IsActive)
Make #IsActive nullable and tweak your SQL code like this:
select ... from ... t
where ...
and (#IsActive is null or t.IsActive = #IsActive)
Plus, refactor your code a tad so that it's more explicit:
public DataTable GetContractors(bool isActive)
{
return GetContractors((bool?)isActive);
}
public DataTable GetAllContractors()
{
return GetContractors(null);
}
private DataTable GetContractors(bool? isActive)
{
SqlParameter paramIsActive = new SqlParameter("#IsActive", SqlDbType.Bit);
paramIsActive.Value = isActive == null ? DBNull.Value : (object)isActive.Value;
DataSet ds = this.SQLDataAccess.ExecSProcReturnDataset(
this.AppConfig.ConnectString, "p_selContractors", paramIsActive);
return ds.Tables[0];
}
change your stored procedure. Have it check if the parameter is null. if it's null, return both active and not active. if it's not null, return the data depending on the parameter.
then in your code, make the parameter nullable, and pass a null when you want to return all records.
In your sproc, make the #isActive parameter nullable
ALTER PROCEDURE p_selContractors ( #isActive bit = null )
Then in your WHERE clause, use the following :-
WHERE
( #isActive IS NULL OR Active = #isActive )
And in your C# code, don't set the #isActive parameter value, and you should be cool.
A quick and easy hack would be to call both procedures seperately and merge the results.
(I'm not saying this is the best option, just one that no-one has suggested yet)
i.e.
var dt = this.SQLDataAccess.ExecSProcReturnDataset(this.AppConfig.ConnectString, "p_selContractors", true).Tables[0];
var dt2 = this.SQLDataAccess.ExecSProcReturnDataset(this.AppConfig.ConnectString, "p_selContractors", false).Tables[0];
dt.Merge(dt2, false);
Related
Modifying an answer from this question slightly, suppose I run this code:
public int SaveOrUpdate(MyEntity entity)
{
var sql = #"MERGE INTO MyEntity
USING
(
SELECT #id as Id
#myField AS MyField
) AS entity
ON MyEntity.Id = entity.Id
WHEN MATCHED THEN
UPDATE
SET Id = #id
MyField = #myField
WHEN NOT MATCHED THEN
INSERT (Id, MyField)
VALUES (#Id, #myField);"
object[] parameters = {
new SqlParameter("#id", entity.Id),
new SqlParameter("#myField", entity.myField)
};
return context.Database.ExecuteSqlCommand(sql, parameters);
}
This will actually run and it returns an int. What does the int mean? The documentation just says
The result returned by the database after executing the command.
I did a couple tests and it looks like it's 1 if it modified a row, and 0 if nothing changed. Is the return value the number of rows modified?
For most databases, that means the number of rows affected by the command. I theory though, god forbid that such a thing exists, the database vendor is free to return whatever and you would then need to look in the documentation for the particular database for what the number means.
I am trying to run a stored procedure returning a single integer value and I can't figure out where its going wrong. From what I've read the following should work but is not and I can't see where I'm going wrong.
Here is my stored procedure:
ALTER PROCEDURE [dbo].[getDDNTempID]
AS
BEGIN
declare #tempID int
select top 1 #tempID = tempID from tblDDNHdr order by tempID asc
if #tempID is null
return 0
else
return #tempID
END
Here is the code where I try to get the return value:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["test"].ConnectionString))
{
SqlCommand cmd = new SqlCommand("getDDNTempID", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection.Open();
Int32 tempID = (Int32)cmd.ExecuteScalar();
if (tempID == 0) { tempID = -1; }
return tempID;
}
When this procedure is called I get a NullReferenceException and the line giving the error is:
Int32 tempID = (Int32)cmd.ExecuteScalar();
I would appreciate any guidance you guys could give.
Thanks
The return function in SQL Server is specifically to return completion codes to the calling function. As such, the values available to be returned are limited. What you need to do instead is to SELECT #tempID and treat it as a result set.
ExecuteScalar returns the value of the first column of the first row of the results. Your stored procedure does not return a result set.
Add a parameter to the SqlCommand.Parameters collection and set the Direction to ReturnValue. It will receive the return value from the stored procedure.
Please note that the return value is intended only for returning a status. You should use an OUTPUT parameter to return #TempId.
I have two instances in my login page depending on what is returned as vat (return variable from the stored procedure below), when I execute the stored procedure on the server the result is INTERNAL, but the the condition on else gets executed instead of INTERNAL on the login page.
string usertype = u.ViewUserType((int)Session["Id"]);
string vattype = u.ViewUserVat((string)Session["Code"]);
if (usertype == "Client")
{
if (vattype == "INTERNAL")
{
Response.Redirect("~/NonIFAClient/");
}
else
{
Response.Redirect("~/Client/");
}
}
public string ViewUserVat(string code)
{
CamOnlineAccess.Utilities u = new CamOnlineAccess.Utilities();
SqlCommand c = u.GetCommandSP("dbo.ViewUserVat");
c.Parameters.AddRange(new System.Data.SqlClient.SqlParameter[] {
new System.Data.SqlClient.SqlParameter("#code",System.Data.SqlDbType.VarChar,50),
new System.Data.SqlClient.SqlParameter("#vat",SqlDbType.VarChar, 50, System.Data.ParameterDirection.Output, false, ((byte)(0)), ((byte)(0)), "", System.Data.DataRowVersion.Current, null)});
c.Parameters["#code"].Value = code;
c.Connection.Open();
c.ExecuteScalar(); // because we have output parameters
c.Connection.Close();
return (string)c.Parameters["#vat"].Value;
}
Stored procedure:
ALTER PROCEDURE [dbo].[ViewUserVat]
-- Add the parameters for the stored procedure here
#code varchar,
#vat varchar(50) output
AS
SELECT
TOP 1 #vat = vattable
FROM
dbo.portfolio
WHERE
owner = #code
Maybe there are spaces or casting issues in the comparrisson
try
c.ExecuteScalar();//because we have output parameters
c.Connection.Close();
String value = (string)c.Parameters["#vat"].Value;
value = value.Trim().ToUpper();
return (string)c.Parameters["#vat"].Value;
There are several ways of returning data from a stored procedure - you can use RETURN, you can perform a plain SELECT and you can use out parameters. The ways to access this values differ and depend on the method - ExecuteScalar, ExecuteNonQuery, ... - used to execute the query. It is also influenced by SET NOCOUNT controlling if the number of affected rows is returned and even - if I remember correctly - the way the stored procedure is declared.
It has been quite some time since I last had to mess with this and I can not remember all the details nor I am aware of a comprehensive list giving all the details. But I am quite sure the following should work for your case.
Change the stored procedure to return a single row with a single column
ALTER PROCEDURE [dbo].[ViewUserVat]
#code varchar
AS
SELECT
TOP 1 vattable
FROM
dbo.portfolio
WHERE
owner = #code
and use the value returned by ExecuteScalar() like this.
public String ViewUserVat(String code)
{
var command = CamOnlineAccess.Utilities().GetCommandSP("dbo.ViewUserVat"))
try
{
command.Parameters.AddWithValue("#code", code);
command.Connection.Open();
return (String)command.ExecuteScalar();
}
finally
{
command.Connection.Close();
command.Dispose();
}
}
Hello Is it possible to store the result of a stored procedure as a true/false value in a bool variable? Something like:
1)
bool var = ExecuteScalar("sp_name", parameters);
or
2)
bool var = ClassName.getValue(parameters);
where
getValue() is a method that has this code:
return dataBase.ExecuteDataSet("sp_name", parameters);
I want to know if a customer has a card or not. I was thinking of using what I have right now which is basically the second option above, and then create a condition whether the row count is more than zero. But I also want to know if there are any other methods I can use.
Thanks in advance.
You can simply do:
DataSet ds = dataBase.ExecuteDataSet("sp_name", parameters);
return ds.Tables[0].Rows.Count>0; //true if record found; false if no rows
Assuming your proc is simply doing a select using the parameters in the where clause. Something like:
select col1 from table a where condition=#parameter
You don't say which DBMS you are using. SQL Server, for example, does not have a bool data type, but you can make your sproc return an int, which you can test for nonzero, e.g.
bool result = ((int) ExecuteScalar("sp_name", parameters)) != 0;
NOTE: I have not tested this, but you could try making the sproc return a bit instead. This is still an integer value as far as SQL Server is concerned, but ADO.NET should detect it and automatically cast it to bool for you. It certainly does for sproc parameters.
ExecuteScalar returns an Object. So no, #1 above would throw an error. Assuming your stored procedure returns a value that can be converted to true/false, you'd have to do something like this:
bool var;
bool.TryParse(ExecuteScalar("sp_name", paramaters).ToString(), out var);
I have a stored Procedure that do some operation and return 1 or 0 as below
CREATE PROCEDURE dbo.UserCheckUsername11
(
#Username nvarchar(50)
)
AS
BEGIN
SET NOCOUNT ON;
IF Exists(SELECT UserID FROM User WHERE username =#Username)
return 1
ELSE
return 0
END
and in C# i want to get this returned value i try ExcuteScalar but it didn't return any value ( i know if i replace return 0 with Select 0 ExcuteScalar will catach it .. but is it any way that allow me to get returned value with replace return with select ?
NOTE : I don't want to user stored procedure output parameter also
In essence you have to define a parameter with "direction" return value.
You can find some examples here: Using ADO.NET with SQL Server and here: Get the Return Value from an SQL Stored Procedure.
Here comes the relevant part from the first link cited:
To get the value of a RETURN
statement, you need to do the
following:
// add a new parameter, with any name we want - its for our own
// use only
SqlParameter sqlParam = com.Parameters.Add("#ReturnValue", SqlDbType.Int);
// set the direction flag so that it will be filled with the return value
myParm.Direction = ParameterDirection.ReturnValue;
Then, after the stored procedure has
been executed,
int returnValue = (int)com.Parameters["#ReturnValue"].Value
will retrieve the value that was set.
When adding parameters, there is a "return value" parameter direction:
var param = cmd.Parameters.Add(cmd.CreateParameter());
param.Direction = System.Data.ParameterDirection.ReturnValue;
Inspect the .Value of this param after the call (ExecuteNonQuery), and you have the return value. One note, though; when using this with SELECT results, the return value is only available after all the data has been read from the results (return/output is at the end of the TDS stream).
You need to add a parameter with a direction = ReturnValue:
using (var command = new SqlCommand("dbo.CheckUsername11", conn)
{ CommandType = CommandType.StoredProcedure })
{
command.Parameters.Add(new SqlParameter("#result") { ParameterDirection.ReturnValue });
command.Parameters.AddWithValue("#Username", username);
command.ExecuteNonQuery();
return (int)command.Parameters["#result"].Value;
}
Check the following URLs it contain the same problem
1- How to get Return Value of a Stored Procedure
2- Getting a Return Value in C# asp.net from a stored procedure (syntax issue)