SQL Server2000 的 OpenXML 特性
SQL Server2000 提供了 OpenXML 特性 , 我们可以很方便的用 OpenXML 特性来代替传统的行集结果 , 同样我们也可以使用定义好的 XML 文档作为输入的数据 , 这样也为我们的数据移植带来的巨大的便利。
同时 ,SQL Server2000 中也提供了存储过程 , 用微软的话说,只有设计成存储过程,才算是 ”cleaner separation of code from the middle-tier” ,这样做是很好的。应用程序访问数据库的数据并不是直接的与数据库表打交道,而是通过存储过程的运行来获取所需要的数据。这样的设计有一个好处就是,避免了频繁的表操作,而通过运行在服务器端的存储过程可以极大的提高运作效率和提升访问数据的速度,同时也很好的屏蔽了数据库表的逻辑,使得数据库访问变成了数据库提供的服务访问。
既然 OpenXML 和存储过程都可以提高 SQL Server2000 的性能 , 那么能否把这种技术结合起来了 ? 答案是肯定的 , 下面我们就来看看怎么在存储过程中使用 OpenXML.
以下是一个使用了 OpenXML 特性的存储过程 :
-------------------------------------------------------------------------------
-- upArchiveMsgInsertMsg
-------------------------------------------------------------------------------
/******************************************************************************
这是一个公文消息xml文档的实例
declare @xml varchar(8000)
SET @xml='
1<archivemsg attachfile="hust" author="湖北" body="hustwelcome" department="mse" receivelist="younther" sendtime=" 1/1/2001 " title="jiangsuer" userid="Admin">
2<msglist userid="Admin"></msglist>
3<msglist userid="Anime"></msglist>
4<msglist userid="Tiger"></msglist>
5</archivemsg>
'
exec upArchiveMsgInsertMsg @xml
*******************************************************************************/
//这个运行存储过程先在ArchiveMsg表中插入一条公文信息,并根据该条公文信息的MsgID和接受者列表,再在MsgList表插入每个接受者的UserID和MsgID,这些信息从xml中获取。
ALTER PROCEDURE upArchiveMsgInsertMsg
(
@xml varchar (8000)
)
AS
DECLARE @idoc int -- xml doc
DECLARE @MsgID int -- new order
DECLARE @SendTime datetime
-- 解析XML文档
EXEC sp_xml_preparedocument @idoc output , @xml
SET NOCOUNT ON
DECLARE @CurrentError int
BEGIN TRANSACTION
-- 开始更新数据的事务
SELECT @SendTime = SendTime
FROM OpenXML ( @idoc , '/ArchiveMsg')
WITH ArchiveMsg
INSERT INTO ArchiveMsg ( Title , UserID , Author , SendTime , Department , ReceiveList , Body , AttachFile )
SELECT Title , UserID , Author , SendTime , Department , ReceiveList , Body , AttachFile
FROM OpenXML ( @idoc , '/ArchiveMsg')
WITH ArchiveMsg
-- 错误检查
SELECT @CurrentError = @@Error
IF @CurrentError != 0
BEGIN
GOTO ERROR_HANDLER
END
SELECT @MsgID = @@IDENTITY
INSERT INTO MsgList ( MsgID , UserID , SendTime )
SELECT @MsgID , UserID , @SendTime
FROM OpenXML ( @idoc , '/ArchiveMsg/MsgList')
WITH (
MsgID int ,
UserID varchar (80),
SendTime datetime
)
-- 错误检查
SELECT @CurrentError = @@Error
IF @CurrentError != 0
BEGIN
GOTO ERROR_HANDLER
END
-- 事务结束
COMMIT TRANSACTION
SET NOCOUNT OFF
-- 从内存中移除定义的XML文档
EXEC sp_xml_removedocument @idoc
RETURN 0
ERROR_HANDLER :
ROLLBACK TRANSACTION
SET NOCOUNT OFF
-- 从内存中移除定义的XML文档
EXEC sp_xml_removedocument @idoc
RETURN @CurrentError
好了 , 存储过程就是这样了 , 我们得测试这个存储过程 , 测试函数代码如下 :
首先我们得生成这个 XML 文档 , 为了简便起见 , 我们就用一个 String 变量来摸拟 XML 文档 :
public string GetXmlString(ArchiveDetail myMsg,string[] useridList)
{
string xml="
";
xml+="
1<archivemsg "+mymsg.attachfilepath+"\"="" "+mymsg.author+"\"="" "+mymsg.body+"\"="" "+mymsg.department+"\"="" "+mymsg.receivelist+"\"="" "+mymsg.sendtime.tostring()+"\"="" "+mymsg.title+"\"="" "+mymsg.userid+"\"="" ";="" xml+="Body=\">";
2
3foreach(string i in useridList)
4
5{
6
7xml+="<msglist userid='\""+i+"\"/'>";
8
9}
10
11xml+="</msglist></archivemsg>
";
return xml;
}
然后就是调用这个存储过程的函数 :
public bool SendArchiveMsg(ArchiveDetail myMsg,string[] useridList)
{
string xml=this.GetXmlString(myMsg,useridList);
try
{
SqlParameter[] prams={ data.MakeInParam("@xml",SqlDbType.VarChar,8000,xml)
<SPAN lang=EN-US style="FONT-SIZE: 9pt; BACKGROUND: #d9d9d9; COLOR: blue; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; ms