项目的需求千变万化,但万变不离其宗,存取显示~只不过用户体验不同。
这不,现在做的项目涉及到对象的存储(需要回滚),这样一来就需要把和对象关联的所有信息都扔到一个存储过程里去,然后通过WCF去请求~~~
废话少说,切入主题:
对象:
实体 ProductFamily -- 有一些自己的基本属性(Title,Description,Status...)
Contacts -- 这个是ProductFamily的关联表,每个ProductFamily有N个Contacts对象,当然这个Contacts不止关联了ProductFamily,还有ProductXXX...等
1. 发送到数据库的xml格式
<?xml version="1.0" encoding="utf-8" ?>
<root>
<User></User>
<ProductFamily>
<ProductFamilyId></ProductFamilyId>
<Title></Title>
<Description></Description>
<!--
...
-->
</ProductFamily>
<Contacts>
<Contact>
<ID></ID>
<TypeID></TypeID>
<ObjectId></ObjectId>
<Alias></Alias>
<Title></Title>
<Name></Name>
</Contact>
<!--
...
N多个Contact对象 -->
</Contacts>
</root>
2. 存储过程
CREATE PROCEDURE [dbo].[PT_ProductFamilyInfoSetXml] @inData XML,
@inUserAlias NVARCHAR(30),
@outProductFamilyId INT = NULL OUTPUT
DECLARE
-- family values
@ProductFamilyId int ,
@Title varchar(100),
@Description varchar(max)
BEGIN TRY
BEGIN TRANSACTION
-----------------------------------------------------------
--Family
-----------------------------------------------------------
-- extract values of family
SELECT
@ProductFamilyId = x.item.value('ProductFamilyId[1]', 'int'),
@Title = x.item.value('Title[1]', 'varchar(100)'),
@Description = x.item.value('Description[1]', 'varchar(max)')
FROM @indata.nodes('/root/ProductFamily') AS x(item)
--ProductFamily update/Insert
IF(@ProductFamilyId IS NULL OR @ProductFamilyId = 0)
BEGIN
INSERT INTO ProductFamily(Title, [Description)
VALUES(@Title,@Description)
SET @outProductFamilyId = SCOPE_IDENTITY()
END
ELSE
BEGIN
UPDATE ProductFamily
SET
Title = @Title,
[Description]=@Description
WHERE ProductFamilyId = @ProductFamilyId
SET @outProductFamilyId = @ProductFamilyId
END
-----------------------------------------------------------
--Contacts
-----------------------------------------------------------
DECLARE @c_id INT,
@c_oid INT = @outProductFamilyId,
@c_tcode int,
@c_alias VARCHAR(512),
@c_name VARCHAR(512),
@c_title VARCHAR(512),
@c_counter INT,
@c_amount INT
IF @inData.exist('/root/Contacts') = 1
BEGIN
SET @c_tcode = (SELECT ContactType.ID FROM ContactType WHERE ContactType.Title LIKE '%family%')
SELECT @c_amount = @indata.value('count(/root/Contacts/*)', 'int')
IF @c_amount > 0
BEGIN
--insert all contacts if create new product family
IF(@ProductFamilyId IS NULL OR @ProductFamilyId = 0)
BEGIN
SET @c_counter = 1
WHILE @c_counter <= @c_amount
BEGIN
SELECT
@c_alias = a.b.value('Alias[1]', 'VARCHAR(512)'),
@c_name = a.b.value('Name[1]', 'VARCHAR(512)'),
@c_title = a.b.value('Title[1]', 'VARCHAR(512)')
FROM @indata.nodes('/root/Contacts/Contact[sql:variable("@c_counter")]') a(b)
SET @c_counter = @c_counter +1
INSERT INTO dbo.ContactObject(TypeCode, ObjectId, Alias, Name, Title, CreatedBy, CreatedDate, ModifiedBy, ModifiedDate)
VALUES(@c_tcode, @c_oid, @c_alias, @c_name, @c_title, @inUserAlias, @Now, @inUserAlias, @Now)
END
END
ELSE
BEGIN
-- delete contacts not exists
SET @c_counter = 1
CREATE TABLE #newCNTS(id INT)
WHILE @c_counter <= @c_amount
BEGIN
SELECT @c_id = CAST(CAST(@inData.query('/root/Contacts/Contact[sql:variable("@c_counter")]/ID/text()') AS VARCHAR(100)) AS INT)
INSERT INTO #newCNTS(id) VALUES (@c_id)
SET @c_counter = @c_counter + 1
END
DELETE FROM dbo.ContactObject
WHERE
ContactObject.ObjectId = @c_oid
AND ContactObject.TypeCode = @c_tcode
AND ContactObject.ID NOT IN(SELECT * FROM #newCNTS)
DROP TABLE #newCNTS
-- update exists contacts
SET @c_counter = 1
WHILE @c_counter <= @c_amount
BEGIN
SELECT
@c_id = a.b.value('ID[1]', 'int'),
@c_alias = a.b.value('Alias[1]', 'VARCHAR(512)'),
@c_name = a.b.value('Name[1]', 'VARCHAR(512)'),
@c_title = a.b.value('Title[1]', 'VARCHAR(512)')
FROM @indata.nodes('/root/Contacts/Contact[sql:variable("@c_counter")]') a(b)
--create a new record if new contact
IF(@c_id IS NULL OR @c_id = 0)
BEGIN
INSERT INTO dbo.ContactObject(TypeCode, ObjectId, Alias, Name, Title, CreatedBy, CreatedDate, ModifiedBy, ModifiedDate)
VALUES(@c_tcode, @c_oid, @c_alias, @c_name, @c_title, @inUserAlias, @Now, @inUserAlias, @Now)
END
ELSE
BEGIN
-- update the record
UPDATE dbo.ContactObject
SET Alias = @c_alias,
Name = @c_name,
Title = @c_title,
ModifiedBy = @inUserAlias,
ModifiedDate = @Now
WHERE ID = @c_id
END
SET @c_counter = @c_counter +1
END
END
END
END
ELSE
BEGIN
DELETE FROM ContactObject
WHERE
ContactObject.ObjectId = @c_oid
AND ContactObject.TypeCode = @c_tcode
END
IF @@ERROR= 0
BEGIN
COMMIT TRANSACTION
END
ELSE
BEGIN
select @@ERROR
ROLLBACK TRANSACTION
END
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
GO
以上存储过程主要涉及到集合操作的增删改,放到这里备个份~~