我有这样一张桌子
我还有另一个表sections
,其中有6个部分的ID来自1 to 6
。我从用户那里获得了一个section id列表,它提供了有关用户当前活动部分的信息。假设返回给我的列表对于标识为{2,3,4,5}
的用户具有以下1
部分ID。现在我的问题是
有人可以告诉我如何实现这个目标吗?
我可以从以下查询中获取total section id's
select Id from sections
但我不知道我会在total list of section id's
之间进行迭代,并比较从C#返回的list of section ids
答案 0 :(得分:0)
回答完整的问题。
<强> 1。就像我在评论中所说:Table valued parameters
首先创建一个UDTT来存储您的部分ID以输入存储过程。
CREATE TYPE [dbo].[SectionIdUDTT] AS TABLE(
[id] int NOT NULL
)
使用此UDTT作为存储过程的参数:
ALTER PROCEDURE [dbo].[YourSPname] @SectionId SectionIdUDTT readonly,
@UserId INT
AS
BEGIN
为了调用此存储过程,必须先填写SectionIdUDTT,然后再调用存储过程。
DECLARE @SectionId AS SectionIdUDTT;
INSERT INTO @SectionId
--your values here
EXEC YourSPname @SectionId, @UserId;
查看DataTable类以便从C#中调用它。确保用户对UDTT具有执行权限。
存储过程中2
将已存在但不在表值参数中的用户的记录设置为非活动状态。
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
只需插入尚不存在的记录即可。我只是假设id
是一个标识列。
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
)
我建议您在存储过程中使用Transaction management。
答案 1 :(得分:0)
首先我创建了一个调用存储过程的方法,对于该方法,我传递了sections
(sections表实体)和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;
}
我从这行xmlString = XMLOperations.WriteXML(lstSections);
得到的xmlString的值就像这样
<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>
现在存储过程
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
生成XMl的另一种方法是使用XElement
这样的
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();