I've a table like this
I've another table sections
in which there are 6 sections with id from 1 to 6
. I get a list of section id from user which gives information about the current active section of user. Suppose the list returned to me has section ids as follows {2,3,4,5}
for user with id 1
. Now my question is
Can anyone please tell me how to achieve this?
I can get total section id's
from the following query
select Id from sections
but don't know i will iterate between total list of section id's
and compare the list of section ids
returned from C#
To answer the complete question.
1. Like I said in the comment: Table valued parameters
First create a UDTT to store your sections ids for input for the stored procedure.
CREATE TYPE [dbo].[SectionIdUDTT] AS TABLE(
[id] int NOT NULL
)
Use this UDTT as a parameter for your stored procedure:
ALTER PROCEDURE [dbo].[YourSPname] @SectionId SectionIdUDTT readonly,
@UserId INT
AS
BEGIN
In order to call this stored procedure you must first fill the SectionIdUDTT before you call the stored procedure.
DECLARE @SectionId AS SectionIdUDTT;
INSERT INTO @SectionId
--your values here
EXEC YourSPname @SectionId, @UserId;
Take a look at DataTable class in order to call this from C#. Make sure the user has execute permissions on the UDTT.
2 in the stored procedure
Set the records to inactive of the user that already existed but are not in the table valued parameter.
UPDATE YourTable
SET IsActive = 0
WHERE UserId = @UserId
AND SectionId NOT IN (SELECT id FROM @SectionId)
AND SectionId IN (SELECT Id FROM sections) --Not really needed
3 in the stored procedure
Just insert the record that not yet exists. I just assume that id
is an identity column.
INSERT INTO YourTable (UserId, SectionId, IsActive)
SELECT @UserId,
s.id,
1
FROM @SectionId s
WHERE NOT EXISTS (
SELECT 1
FROM YourTable y
WHERE y.SectionId = s.id
AND y.UserId = @UserId
)
I would recommend Transaction management in your stored procedure.
First I created a method which would call stored procedure, to that method I passed a list of sections
(sections table entity) and Customer Id
public bool SaveChatSectionUserMapping(List<Sections> lstSections, int customerId)
{
con = new SqlConnection(connectionString);
bool isUpdated = false;
try
{
string xmlString = string.Empty;
xmlString = XMLOperations.WriteXML(lstSections);
SqlCommand cmd = new SqlCommand("spUpdateSections", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@XMLData", SqlDbType.Xml).Value = xmlString;
cmd.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
SqlParameter param = new SqlParameter();
param.SqlDbType = SqlDbType.Bit;
param.Direction = ParameterDirection.Output;
param.ParameterName = "@Result";
cmd.Parameters.Add(param);
con.Open();
cmd.ExecuteNonQuery();
isUpdated = (param.Value != DBNull.Value) ? Convert.ToBoolean(param.Value) : false;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (con.State == ConnectionState.Open)
con.Close();
}
return isUpdated;
}
The value of xmlString I get from this line xmlString = XMLOperations.WriteXML(lstSections);
is like this
<ArrayOfSection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Sections>
<UserId>1</UserId>
<SectionId>1</SectionId>
<IsActive>true</IsActive>
</Sections>
<Sections>
<UserId>1</UserId>
<SectionId>2</SectionId>
<IsActive>true</IsActive>
</Sections>
<Sections>
<UserId>1</UserId>
<SectionId>5</SectionId>
<IsActive>true</IsActive>
</Sections>
</ArrayOfSection>
Now in stored Procedure
CREATE Procedure [dbo].[spUpdateSections]
(
@XMLData as XML,
@CustomerId INT,
@Result int Output
)
AS
BEGIN
SET NOCOUNT ON;
Declare @ErrorCode Varchar(100) = '',@propertyCount VArchar(100) = '',@currentCount int=1,@SectionId int, @IsActive bit
Begin TRY
UPDATE Sections
SET
IsActive = 0
WHERE
UserId = @CustomerId
SELECT @propertyCount = convert(VARCHAR, @XMLData.query ('count(/ArrayOfSection/Sections)'))
SET @currentCount = 1
while (@currentCount<=@propertyCount)
Begin
SET @SectionId = @XMLData.value('data(/ArrayOfSection/Sections[sql:variable("@currentCount")]/SectionId)[1]', 'INT')
SET @IsActive = @XMLData.value('data(/ArrayOfSection/Sections[sql:variable("@currentCount")]/IsActive)[1]', 'BIT')
If Exists (SELECT *
FROM
Sections
WHERE
UserId = @CustomerId
AND SectionId = @SectionId)
BEGIN
IF(@IsActive=1)
BEGIN
UPDATE Sections
SET
IsActive = 1
WHERE
UserId = @CustomerId AND
SectionId = @SectionId
END
END
ELSE
BEGIN
IF(@IsActive=1)
BEGIN
INSERT INTO Sections
([SectionId]
,[UserId]
,[IsActive])
VALUES
(@SectionId,@CustomerId,1)
END
END
SET @currentCount = @currentCount + 1
End
SET @Result = 1
ErrorCode:
If(@ErrorCode !='')
BEGIN
--SELECT @BSErrorResult = doctor.GetErrorCodeDetail(@ErrorCode)
SET @Result = 2
END
END TRY
BEGIN CATCH
--Declaring Variable for formating error
Declare @ErrorMessage VARCHAR(max),
@ErrorSeverity INT,
@ErrorState INT
--SELECTING TECHNICAL ERROR
SELECT @ErrorMessage = error_message()
, @ErrorSeverity = error_severity()
, @ErrorState = error_state()
, @ErrorMessage = @ErrorMessage + ' ' + db_name() + ' ' + ' ' + object_name(@@PROCID);
RAISERROR (
@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
End CATCH
END
Another way to Generate XMl would be by using XElement
like this
XElement xml = new XElement("Sections",
from col in lstSections
select new XElement("rows",
new XElement("UserId", col.UserId),
new XElement("SectionId", col.SectionId),
new XElement("IsActive", col.IsActive)));
string xmlString = xml.ToString();
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.