[英]Update or Insert records in database based on result set
我有這樣的桌子
我還有另一個表sections
,其中有6個節,其ID從1 to 6
。 我從用戶那里獲得了部分ID的列表,該列表提供了有關用戶當前活動部分的信息。 假設返回給我的列表具有ID為1
用戶,其區段ID如下{2,3,4,5}
所示。 現在我的問題是
誰能告訴我如何實現這一目標?
我可以從以下查詢中獲取total section id's
select Id from sections
但不知道我會在total list of section id's
之間進行迭代,並比較從C#返回list of section ids
的list of section ids
回答完整的問題。
1.就像我在評論中說的: 表值參數
首先創建一個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
)
我建議您在存儲過程中進行事務管理 。
首先,我創建了一個將調用存儲過程的方法,向該方法傳遞了一個sections
列表(節表實體)和客戶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的值xmlString = XMLOperations.WriteXML(lstSections);
就是這樣
<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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.