项目的需求千变万化,但万变不离其宗,存取显示~只不过用户体验不同。

这不,现在做的项目涉及到对象的存储(需要回滚),这样一来就需要把和对象关联的所有信息都扔到一个存储过程里去,然后通过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
       

  

 以上存储过程主要涉及到集合操作的增删改,放到这里备个份~~

相关文章: