I have this stored procedure:
ALTER PROCEDURE [dbo].[DeleteFromSchoolMain]
@TblName VARCHAR(50),
@MainID VARCHAR(10),
@TblCol VARCHAR(50),
@rowsCount INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @RelTbl AS Nvarchar(50)
DECLARE @ColForFK AS Nvarchar(50)
DECLARE @TblMaterial AS NVARCHAR(50)
DECLARE @ColMaterialID AS NVARCHAR(50)
DECLARE @ColMaterialFK AS NVARCHAR(50)
DECLARE @cmdForMaterial AS NVARCHAR(max)
DECLARE @TblSubject AS NVARCHAR(50)
DECLARE @ColSubjectID AS NVARCHAR(50)
DECLARE @ColSubjectFK AS NVARCHAR(50)
DECLARE @cmdForSubject AS NVARCHAR(max)
Set @ColForFK = SUBSTRING(@TblCol,1, DATALENGTH(@TblCol)-2)
Set @ColForFK = @ColForFK+'FK'
DECLARE @cmd AS NVARCHAR(max)
DECLARE @TempCount int
SET @MainID = ''''+@MainID+ ''''
SET @RelTbl = 'ClassSubMatRelation'
--For Class Material
SET @TblMaterial = 'ClassMaterial'
SET @ColMaterialID = 'ClassMaterialID'
SET @ColMaterialFK = 'ClassMaterialFK'
SET @cmd = N'UPDATE ' + @RelTbl + ' SET Status_Info = 0 WHERE ' + @ColForFK + ' = ' + @MainID -- Delete from ClassRelation Table
EXEC(@cmd)
SET @TempCount = @@ROWCOUNT
SET @rowsCount = @TempCount + @rowsCount;
SET @cmd = N'UPDATE ' + @TblName + ' SET Status_Info = 0 WHERE ' + @TblCol + ' = ' + @MainID -- Delete from Main Table
EXEC(@cmd)
SET @TempCount = @@ROWCOUNT
SET @rowsCount = @TempCount + @rowsCount;
-------------------------------------Board-----------------------------------
IF (@TblName = 'Board')
BEGIN
SET @cmdForMaterial = N'UPDATE '+@TblMaterial+' Set Status_Info = 0 where '+@ColMaterialID+' in ( Select s.'+@ColMaterialFK+' from '+@RelTbl+' s where s.' + @ColForFK + ' = ' + @MainID + ' AND s.ClassSubjectFK IN ( SELECT T.ClassSubjectFK FROM ' + @RelTbl + ' T WHERE T.'+@ColForFK+' = '+ @MainID + ') and s.ClassSubjectFK NOT IN ( SELECT E.ClassSubjectFK FROM ' +@RelTbl+' E WHERE E.'+@ColForFK+' != '+ @MainID +') and s.'+@ColMaterialFK+' is not null )'
EXEC(@cmdForMaterial)
SET @TempCount = @@ROWCOUNT
SET @rowsCount = @TempCount + @rowsCount;
SET @TempCount = 0;
--For Class Subject
SET @TblMaterial = 'ClassSubject'
SET @ColMaterialID = 'ClassSubjectID'
SET @ColMaterialFK = 'ClassSubjectFK'
SET @cmdForMaterial = N'UPDATE '+@TblMaterial+' Set Status_Info = 0 where '+@ColMaterialID+' in ( Select s.'+@ColMaterialFK+' from '+@RelTbl+' s where s.' + @ColForFK + ' = ' + @MainID + ' AND s.ClassSubjectFK IN ( SELECT T.ClassSubjectFK FROM ' + @RelTbl + ' T WHERE T.'+@ColForFK+' = '+ @MainID + ') and s.ClassSubjectFK NOT IN ( SELECT E.ClassSubjectFK FROM ' +@RelTbl+' E WHERE E.'+@ColForFK+' != '+ @MainID +') and s.'+@ColMaterialFK+' is not null )'
EXEC(@cmdForMaterial)
SET @TempCount = @@ROWCOUNT
SET @rowsCount = @TempCount + @rowsCount;
SET @TempCount = 0;
END
------------------------------ Class Subject ------------------------------------
ELSE IF (@TblName = 'ClassSubject')
BEGIN
SET @cmdForMaterial = N'UPDATE '+@TblMaterial+' Set '+@TblMaterial+'.Status_Info = 0 from '+@TblMaterial+' tm join '+@RelTbl+' rt on rt.'+@ColMaterialFK+' = tm.'+@ColMaterialID+' where rt.'+@ColForFK+ ' = '+ @MainID
EXEC(@cmdForMaterial)
SET @TempCount = @@ROWCOUNT
SET @rowsCount = @TempCount + @rowsCount;
SET @TempCount = 0;
END
END
GO
And I'm executing it in C# like this:
var rowsAffected = 0;
using (SqlConnection conn = new SqlConnection(Constants.Connection))
{
conn.Open();
SqlCommand cmd = new SqlCommand("DeleteFromSchoolMain", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@TblName", abundleBoard.TempName);
cmd.Parameters.AddWithValue("@MainID", abundleBoard.MainID.ToString());
cmd.Parameters.AddWithValue("@TblCol", abundleBoard.TblCol);
SqlParameter outputParam = new SqlParameter();
outputParam.ParameterName = "@rowsCount";
outputParam.SqlDbType = System.Data.SqlDbType.Int;
outputParam.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(outputParam);
object o = cmd.ExecuteScalar();
if (!outputParam.Value.Equals(DBNull.Value))
{
rowsAffected = Convert.ToInt32(outputParam.Value);
string q = o.ToString();
}
conn.Close();
}
But my problem is I'm not getting anything in output parameter. I don't understand the problem, also I feels like my stored procedure is not optimised. Is there anything I can do to make the queries execute faster? Indexing and partitioning I've done my level best already.
EDIT:
So with help of @SurjitSD and @PeterB I got a resolution:-
In my Procedure I added the line at Top :-
SET @rowsCount=0
And in c# I've changed the code like :-
cmd.ExecuteNonQuery();
if (!cmd.Parameters["@rowsCount"].Value.Equals(DBNull.Value))
{
rowsAffected = Convert.ToInt32(cmd.Parameters["@rowsCount"].Value);
}
For Now this works fine!
You are calling ExecuteScalar
in c#.
ExecuteScalar
will give you firstRow and FirstColumn value returned by Select
statement in procedure.
You need to use ExecuteNonQuery
After ExecuteNonQuery
, you can get value like
cmd.Parameters["@rowsCount"].Value
You can also get value using
ExecuteScalar
if you useSelect @rowsCount
afterset @rowsCount
. Then you dont need to mentionoutput direction
to any parameter, both in sql and c#
Example with ExecuteScalar
Sql procedure
Alter procedure SomeProcedure
(
@someVariable int
:
:
)
Begin
/*Some processing logic of procedure*/
Select @SomeVariable //any variable Or Value from procedure needed as output in c#
End
C#
var result = cmd.ExecuteScalar();
——- Edit ——
The actual reason for not getting value in c# was (with explanation)
The parameter @rowsCount
was not initialized before using. So it was null
and when doing SET @rowsCount = @TempCount + @rowsCount
, its actually adding something to null
. And adding anything to null
will be null
as result.
So @rowsCount
was always null
. Setting @rowsCount=0
in begining of procedure helped.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.