欢迎来到个人简历网!永久域名:gerenjianli.cn (个人简历全拼+cn)
当前位置:首页 > 范文大全 > 实用文>SQL用XML数据类型进行数据建模

SQL用XML数据类型进行数据建模

2023-08-31 08:13:01 收藏本文 下载本文

“新奇”通过精心收集,向本站投稿了10篇SQL用XML数据类型进行数据建模,下面是小编为大家整理后的SQL用XML数据类型进行数据建模,供大家参考借鉴,希望可以帮助到有需要的朋友。

SQL用XML数据类型进行数据建模

篇1:SQL用XML数据类型进行数据建模

相同或不同的表

XML 数据类型列可以在包含其他关系列的表中创建,也可以在与主表之间具有外键关系的独立表中创建,

在满足下列某个条件时,请在同一个表中创建 XML 数据类型列:

• 您的应用程序在 XML 列上执行数据检索,并且不需要 XML 列上的 XML 索引。 或者

• 您需要在 XML 数据类型列上生成 XML 索引,并且主表的主键与其聚集键相同。有关详细信息,请参阅将 XML 数据类型列编入索引一节。

在满足下列条件时,请在单独的表中创建 XML 数据类型列:

• 您需要在 XML 数据类型列上生成 XML 索引,但主表的主键与其聚集键不同,或者主表不具有主键,或者主表是一个堆(也就是说,没有聚集键)。如果主表已经存在,则这可能是真的。

• 您不希望表扫描由于表中存在 XML 列(无论它是存储在行中还是存储在行外,都会占用空间)而降低速度。

XML 数据的粒度

XML 列中存储的 XML 数据的粒度对于锁定和更新特性而言至关重要。SQL Server 对 XML 和非 XML 数据采用了相同的锁定机制。因此,行级锁定会导致相应行中的所有 XML 实例被锁定。当粒度比较大时,锁定大型 XML 实例以便进行更新会导致多用户场合下的吞吐量下降。另一方面,严重的分解会丢失对象封装并提高重新组合成本。

对 XML 实例进行更新会将现有实例替换为更新后的实例,即使只修改单个属性的值。XML 数据粒度越大,更新成本就越高。较小的 XML 实例会产生较高的更新性能。

对于良好的设计而言,重要的是保持数据建模需要与锁定和更新特性之间的平衡。

非类型化、类型化和受约束的 XML 数据类型

SQL Server 2005 XML 数据类型实现了 ISO SQL- 标准 XML 数据类型。因此,它可以在非类型化 XML 列中存储格式规范的 XML 1.0 文档以及带有文本节点和任意数量顶级元素的所谓的 XML 内容片段。系统将检查数据的格式是否规范,不要求将列绑定到 XML 架构,并且拒绝在扩展意义上格式不规范的数据。对于非类型化 XML 变量和参数,也是如此。

如果您具有描述 XML 数据的 XML 架构,则可以将这些架构与 XML 列相关联,以便产生类型化 XML。XML 架构用于对数据进行有效性验证,在查询和数据修改语句编译过程中执行比非类型化 XML 更准确的类型检查,以及优化存储和查询处理。

在下列条件下,请使用非类型化 XML 数据类型:

• 您没有对应于 XML 数据的架构

• 您拥有架构,但不希望服务器对数据进行有效性验证。当应用程序在服务器中存储数据之前执行客户端验证时,或者暂时存储根据架构无效的 XML 数据时,或者使用在服务器中不受支持的架构组件(例如 key/keyref)时,有时会出现这种情况。

在下列条件下,请使用类型化 XML 数据类型:

• 您拥有对应于 XML 数据的架构,并且希望服务器按照 XML 架构对 XML 数据进行有效性验证。

• 您希望充分利用基于类型信息的存储和查询优化。

• 您希望在查询的编译过程中更充分地利用类型信息。

类型化 XML 列、参数和变量可以存储 XML 文档或内容 - 您在声明时必须将它们指定为标志(分别指定为 DOCUMENT 或 CONTENT)。而且,您必须提供 XML 架构集合。如果每个 XML 实例恰好有一个顶级元素,请指定 DOCUMENT;否则,请使用 CONTENT。查询编译器在查询编译过程的类型检查中使用 DOCUMENT 标记来推理唯一的顶级元素。

除了将 XML 列类型化以外,您还可以在类型化或非类型化 XML 数据类型列上使用关系(列或行)约束。在下列条件下,请使用约束:

• 无法在 XML 架构中表示业务规则。例如,花店的送货地址必须在其营业地点周围 50 英里范围之内,这可以编写为 XML 列上的约束。该约束可能涉及到 XML 数据类型方法。

• 您的约束涉及到表中的其他 XML 列或非 XML 列。这方面的一个例子是:强制 XML 实例中存在的 Customer ID (/Customer/@CustId) 与关系 CustomerID 列中的值匹配。

文档类型定义 (DTD)

XML 数据类型列、变量和参数可以使用 XML 架构而不是 DTD 加以类型化。然而,对于非类型化和类型化 XML,都可以使用内联 DTD 来提供默认值,以便将实体引用替换为它们的扩展形式。

您可以使用第三方工具将 DTD 转化为 XML 架构文档,并且将 XML 架构加载到数据库中。

将 XML 数据类型列编入索引

可以在 XML 数据类型列上创建 XML 索引。这会将该列中 XML 实例上的所有标记、值和路径编入索引,从而提高查询性能。在下列条件下,您的应用程序可能受益于 XML 索引:

• 对 XML 列进行查询在您的工作负荷中很常见。必须考虑数据修改过程中的 XML 索引维护成本。

• XML 值相对较大,而检索的部分相对较小。生成索引可以避免在运行时分析全部数据,并且因为受益于索引查找而提高查询处理的性能。

XML 列上的第一个索引是“主 XML 索引”。通过该索引,可以在 XML 列上创建三种类型的辅助 XML 索引,从而提高常见种类的查询的速度,如下节所述。

主 XML 索引

这会将 XML 列中的 XML 实例内部的所有标记、值和路径编入索引。基表(即包含 XML 列的表)必须在该表的主键上具有聚集索引;主键用于将索引行与基表中的行相关联。从 XML 列中检索完整的 XML 实例(例如 SELECT *)。查询使用主 XML 索引,并返回标量值或使用索引本身的 XML 子树。

示例:创建主 XML 索引

在我们的多数示例中,都使用带有非类型化 XML 列的表 T (pk INT PRIMARY KEY, xCol XML),这些示例都可以简单地扩展为类型化 XML 的形式(有关使用类型化 XML 的信息,请参阅 SQL Server 2005 联机图书)。为了便于说明,将针对如下所示的 XML 数据实例描述查询:

Writing Secure Code

Michael

Howard

David

LeBlanc

39.99

下面的语句在表 T 的 XML 列 xCol 上创建了名为 idx_xCol 的 XML 索引:

CREATE PRIMARY XML INDEX idx_xCol on T (xCol)

辅助 XML 索引

在创建主 XML 索引之后,您可能希望创建辅助 XML 索引来提高工作负荷中的不同种类查询的速度。三种类型的辅助 XML 索引 - PATH、PROPERTY 和 VALUE 分别为基于路径的查询、自定义属性管理场合和基于值的查询提供帮助。PATH 索引在列中的所有 XML 实例上,按照文档顺序生成各个 XML 节点的 (path, value) 对的 B+ 树。PROPERTY 索引创建各个 XML 实例中 (PK, path, value) 对的聚集 B+ 树,其中 PK 是基表的主键。最后,VALUE 索引在 XML 列中的所有 XML 实例中,按照文档顺序创建各个节点的 (value, path) 对的 B+ 树。

以下是创建上述一个或多个索引的一些准则:

• 如果工作负荷大量使用 XML 列中的路径表达式,则 PATH 辅助 XML 索引可能会加快工作负荷的处理速度。最常见的例子是在 T-SQL 的 WHERE 子句中对 XML 列使用 exist 方法。

• 如果您的工作负荷从单独的使用路径表达式的 XML 实例中检索多个值,则将各个 XML 实例中的路径聚集到 PROPERTY 索引中可能会很有用。这种情况通常出现在属性包场合中,此时对象的属性被获取并且其主键值已知。

• 如果您的工作负荷涉及到查询 XML 实例中的值,而不知道包含这些值的元素或属性名称,则您可能需要创建 VALUE 索引。这通常发生在子代轴查找中,例如 //author[last-name=“Howard”],其中 元素可以出现在层次结构的任意级别上。这种情况还会发生在“通配符”查询中,例如

/book [@* = “novel”],其中查询将查找具有某个值为 “novel” 的属性的 元素。

示例:基于路径的查找

假设下面的查询在您的工作负荷中很常见:

SELECT pk, xCol

FROM T

WHERE xCol.exist ('/book[@genre = “novel”]') = 1

路径表达式 /book/@genre 和值 “novel” 对应于 PATH 索引的键字段。因此,PATH 类型的辅助 XML 索引对于该工作负荷很有用:

CREATE XML INDEX idx_xCol_Path on T (xCol)

USING XML INDEX idx_xCol FOR PATH

示例:获取对象的属性

请考虑下面的查询,它从表 T 的各个行中检索一本书的属性“genre”、“title”和 ISBN:

SELECT xCol.value ('(/book/@genre)[1]', 'varchar(50)'),

xCol.value ('(/book/title)[1]', 'varchar(50)'),

xCol.value ('(/book/@ISBN)[1]', 'varchar(50)')

FROM T

在这种情况下,属性索引很有用,其创建方式如下所示:

CREATE XML INDEX idx_xCol_Property on T (xCol)

USING XML INDEX idx_xCol FOR PROPERTY

示例:基于值的查询

在以下查询中,子代轴或自身轴 (//) 指定了部分路径,以便基于 ISBN 值的查找可以因为使用 VALUE 索引而受益:

SELECT xCol

FROM T

WHERE xCol.exist ('//book[@ISBN = “1-8610-0157-6”]') = 1

VALUE 索引按如下方式创建:

CREATE XML INDEX idx_xCol_Value on T (xCol)

USING XML INDEX idx_xCol FOR VALUE

XML 列上的全文索引

您可以在 XML 列上创建全文索引,从而将 XML 值的内容编入索引,而忽略 XML 标记。属性值没有被编入全文索引(因为它们被视为标记的一部分),并且元素标记被用作标记边界。在某些情况下,可以将全文搜索与 XML 索引用法结合起来:

• 首先,使用 SQL 全文搜索筛选感兴趣的 XML 值。

• 接下来,查询这些 XML 值,这会使用 XML 列上的 XML 索引。

示例:将全文搜索与 XML 查询结合起来

在 XML 列上创建全文索引之后,以下查询将检查 XML 值是否在书名中包含单词“custom”:

SELECT *

FROM T

WHERE CONTAINS(xCol,'custom')

AND xCol.exist('/book/title/text()[contains(.,“custom”)]') =1

CONTAINS() 方法使用全文索引,将文档中任何地方包含单词“custom”的 XML 值组合为一个子集。exist() 子句确保单词“custom”出现在书名中。

使用 CONTAINS() 和 XQuery contains() 的全文搜索具有不同的语义。后者是子字符串匹配,而前者则是使用单词衍生的标记匹配。因此,如果要搜索标题中的字符串 “run”,则 “run”、“runs” 和 “running” 都将匹配,因为全文 CONTAINS() 和 Xquery contains() 都满足。然而,上述查询不匹配标题中的单词“customizable”。(全文 CONTAINS() 失败,而 Xquery contains() 被满足)。通常,对于纯粹的子字符串匹配,应该删除全文 CONTAINS() 子句。

而且,全文搜索采用单词衍生,而 XQuery contains() 是一种字面匹配。这一区别将在下一个示例中阐述。

示例:使用单词衍生对 XML 值进行全文搜索

通常情况下,不能排除示例:将全文搜索与 XML 查询结合起来中的 XQuery contains() 检查。请考虑查询:

SELECT *

FROM T

WHERE CONTAINS(xCol,'run')

因为使用单词衍生,所以文档中的单词“ran”匹配搜索条件。而且,使用 XQuery 时不会检查搜索上下文。

在使用被全文索引的 AXSD 将 XML 分解到关系列中时,XML 视图上的 XPath 查询不会对基础表执行全文搜索。

属性提升

如果主要是对少量元素和属性值进行查询(例如,基于客户 ID 查找客户,即指定了 /Customer/@CustId 的值),您可能希望将这些数量提升到关系列中。当检索了整个 XML 实例,但只对一小部分 XML 数据进行查询时,这将很有用。在 XML 列上创建 XML 索引是没有必要的;相反,可以将被提升的列编入索引。必须编写查询以使用提升的列(即,查询优化器不会将对 XML 列的查询重新定向到提升的列)。

提升的列可以是同一表中的计算列,也可以是表中单独的、用户维护的列。当从各个 XML 实例中提升唯一值(即单值属性)时,这已足够,

然而,对于多值属性,您必须为该属性创建单独的表,如下所述。

基于 XML 数据类型的计算列

可以使用能够激活 XML 数据类型方法的用户定义函数 (UDF) 来创建计算列。计算列的类型可以是任何 SQL 类型,包括 XML。以下示例说明了这一点。

示例:基于 XML 数据类型方法的计算列

为书籍的 ISBN 创建用户定义的函数:

CREATE FUNCTION udf_get_book_ISBN (@xData xml)

RETURNS varchar(20)

BEGIN

DECLARE @ISBN varchar(20)

SELECT @ISBN = @xData.value('/book[1]/@ISBN', 'varchar(20)')

RETURN @ISBN

END

为 ISBN 向表中添加一个计算列:

ALTER TABLE T

ADD ISBN AS dbo.udf_get_book_ISBN(xCol)

可以用通常的方式将计算列编入索引。

示例:基于 XML 数据类型方法的计算列上的查询

要获取其 ISBN 为 0-7356-1588-2 的 ,可以改写 XML 列上的查询

SELECT xCol

FROM T

WHERE xCol.exist ('/book[@ISBN = “0-7356-1588-2”]') = 1

以使用计算列,如下所示:

SELECT xCol

FROM T

WHERE ISBN = '0-7356-1588-2'

可以创建一个用户定义的函数,返回 XML 数据类型和使用该 UDF 的计算列。然而,无法在计算的 XML 列上创建 XML 索引。

创建属性表

您可能希望将 XML 数据中的某些多值属性提升到一个或多个表中,在这些表上创建索引,并且重定向查询以使用这些表。典型的情形是一小部分属性覆盖了大部分查询工作负荷。您可以执行以下操作:

• 创建一个或多个表以存放多值属性。您可能发现采用以下处理方式会很方便:每个表存储一个属性,并且在属性表中复制基表的主键以便与基表进行向后联接。

• 如果您希望保持属性的相对顺序,则需要为相对顺序引入一个单独的列。

• 在 XML 列上创建触发器以便维护属性表。在触发器中,执行以下操作:

• 使用 XML 数据类型方法(如 nodes() 和 value())在属性表中插入和删除行。(有关 nodes() 方法的详细信息,请参阅 Value()、Nodes() 和 OpenXML()。)

• 在 CLR 中创建流式表值函数,以便在属性表中插入和删除行。

• 编写查询,以便对属性表进行 SQL 访问,以及对基表中的 XML 列进行 XML 访问,这需要使用这些表的主键将其相互联接。

示例:创建属性表

假设您希望提升作者的名字。书籍有一个或多个作者,因此名字是一个多值属性。每个名字都存储在属性表的单独行中。在属性表中复制了基表的主键以便向后联接。

create table tblPropAuthor (propPK int, propAuthor varchar(max))

示例:创建用户定义的函数以便从 XML 实例生成行集

下面的表值函数 udf_XML2Table 接受一个主键值和一个 XML 实例。它将检索 元素的所有作者的名字,并返回(主键,名字)对行集。

create function udf_XML2Table (@pk int, @xCol xml)

returns @ret_Table table (propPK int, propAuthor varchar(max))

with schemabinding

as

begin

insert into @ret_Table

select @pk, nref.value('.', 'varchar(max)')

from @xCol.nodes('/book/author/first-name') R(nref)

return

end

示例:创建触发器以填充属性表

插入触发器:在属性表中插入行

create trigger trg_docs_INS on T for insert

as

declare @wantedXML xml

declare @FK int

select @wantedXML = xCol from inserted

select @FK = PK from inserted

insert into tblPropAuthor

select * from dbo.udf_XML2Table(@FK, @wantedXML)

删除触发器:基于删除行的主键值,从属性表中删除行

create trigger trg_docs_DEL on T for delete

as

declare @FK int

select @FK = PK from deleted

delete tblPropAuthor where propPK = @FK

更新触发器:在与更新的 XML 实例对应的属性表中删除现有行,并且在该属性表中插入新行

create trigger trg_docs_UPD

on T

for update

as

if update(xCol) or update(pk)

begin

declare @FK int

declare @wantedXML xml

select @FK = PK from deleted

delete tblPropAuthor where propPK = @FK

select @wantedXML = xCol from inserted

select @FK = pk from inserted

insert into tblPropAuthor

select * from dbo.udf_XML2Table(@FK, @wantedXML)

end

示例:查找作者的名字为“David”的 XML 实例

可以在 XML 列上表示该查询。另外,还可以在属性表中搜索名字“David”,然后与基表执行向后联接以返回 XML 实例,如下所示:

SELECT xCol

FROM T JOIN tblPropAuthor ON T.pk = tblPropAuthor.propPK

WHERE tblPropAuthor.propAuthor = 'David'

示例:使用 CLR 流式表值函数的解决方案

该解决方案包括以下步骤:(a) 定义 CLR 类 SqlReaderBase,它实现了 ISqlReader,并且通过在 XML 实例上应用路径表达式来生成流式表值输出;(b) 创建一个程序集和一个 T-SQL 用户定义函数 (UDF) 来激活该 CLR 类;(c) 使用 UDF 定义插入、更新和删除触发器,以维护属性表。

首先,创建流式 CLR 函数,其主干如下所示。XML 数据类型被公开为 ADO.NET 中的托管类 SqlXml;它支持返回 XmlReader 的方法 CreateReader()。

public class c_streaming_xml_tvf {

public static ISqlReader streaming_xml_tvf

(SqlXml xmlDoc, string pathExpression) {

return (new TestSqlReaderBase (xmlDoc, pathExpression));

}

}

// Class that implements ISqlReader

public class TestSqlReaderBase : ISqlReader {

XPathNodeIterator m_iterator;

???public SqlChars FirstName;

// Metadata for current resultset

private SqlMetaData[] m_rgSqlMetaData;

public TestSqlReaderBase (SqlXml xmlDoc, string pathExpression) {

// Variables for XPath navigation

XPathDocument xDoc;

XPathNavigator xNav;

XPathExpression xPath;

// Set sql meta. data

m_rgSqlMetaData = new SqlMetaData[1];

m_rgSqlMetaData[0] = new SqlMetaData (“FirstName”,

SqlDbType.NVarChar,50);

//Set up the Navigator

if (!xmlDoc.IsNull)

xDoc = new XPathDocument (xmlDoc.CreateReader());

else

xDoc = new XPathDocument ();

xNav = xDoc.CreateNavigator();

xPath = xNav.Compile (pathExpression);

m_iterator = xNav.Select(xPath);

}

public bool Read() {

bool moreRows = true;

if (moreRows = m_iterator.MoveNext())

???FirstName = new SqlChars (m_iterator.Current.Value);

return moreRows;

}

}

接下来,创建一个程序集,以及一个与 CLR 函数 streaming_xml_tvf 对应的 T-SQL 用户定义函数 SQL_streaming_xml_tvf(未显示)。该 UDF 用于定义表值函数 CLR_udf_XML2Table 以便生成行集:

create function CLR_udf_XML2Table (@pk int, @xCol xml)

returns @ret_Table table (FK int, FirstName varchar(max))

with schemabinding

as

begin

insert into @ret_Table

select @pk, FirstName

FROM SQL_streaming_xml_tvf (@xCol, '/book/author/first-name')

return

end

最后,定义触发器,如示例创建触发器以填充属性表中所示,但用函数 CLR_udf_XML2Table 替换 udf_XML2Table。因此,插入触发器将如下所示:

create trigger CLR_trg_docs_INS on T for insert

as

declare @wantedXML xml

declare @FK int

select @wantedXML = xCol from inserted

select @FK = PK from inserted

insert into tblPropAuthor

select *

from dbo.CLR_udf_XML2Table(@FK, @wantedXML)

删除触发器与非 CLR 版本完全相同,而更新触发器只是将函数 udf_XML2Table() 替换为 CLR_udf_XML2Table()。

XML 架构集合

XML 架构集合是一个元数据实体,其范围由关系架构确定,包含一个或多个可能相关(例如,通过 )或无关的 XML 架构。XML 架构集合中的单独 XML 架构由其目标命名空间标识。

XML 架构集合是使用 CREATE XML SCHEMA COLLECTION 语法创建的,并且提供了一个或多个 XML 架构。可以向现有 XML 架构中添加更多的 XML 架构组件,并且可以使用 ALTER XML SCHEMA COLLECTION 语法向 XML 架构集合中添加更多的架构。可以使用 SQL Server 2005 中的安全模型像任何 SQL 对象那样保证 XML 架构集合的安全。

多类型化列

XML 架构集合 C 按照多个 XML 架构将 XML 列 xCol 类型化。此外,标志 DOCUMENT 或 CONTENT 分别指定 XML 树或片段是否可以存储在列 xCol 中。

对于 DOCUMENT,每个 XML 实例都会按照用来对其进行验证和类型化的命名空间,指定实例中顶级元素的目标命名空间。另一方面,对于 CONTENT,每个顶级元素都可以指定 C 中的任一目标命名空间。XML 实例将按照实例中存在的所有目标命名空间进行验证和类型化。

架构演变

XML 架构集合用于类型化 XML 列、变量和参数。它提供了一种 XML 架构演变机制。假设您将带有目标命名空间 BOOK-V1 的 XML 架构添加到 XML 架构集合 C 中。使用 C 加以类型化的 XML 列 xCol 可以存储符合 BOOK-V1 架构的 XML 数据。

假设某个应用程序希望通过新的架构组件(例如复杂类型定义和顶级元素声明)来扩展 XML 架构。这些新的架构组件可以添加到 BOOK-V1 架构中,并且不要求对列 xCol 中的现有 XML 数据进行重新验证。

假设该应用程序后来希望提供该 XML 架构的新版本,并且为该新版本选择目标命名空间 BOOK-V2。该 XML 架构可以添加到 C 中。XML 列可以存储 BOOK-V1 和 BOOK-V2 二者的实例,并且对符合这些命名空间的 XML 实例执行查询和数据修改。

篇2:用触发器对SQL Server数据库进行数据备份备份恢复

问:如何用触发器对SQL Server数据库进行数据备份?

答:首先,你需要建立测试数据表,一个用于插入数据:test3,另外一个作为备份:test3_bak

以下是引用片段:

create table test3(id int primary key not null

identity(1,1),uname varchar(20),uage int);

create table test3_bak(id int primary key not

null identity(1,1),bid int,uname varchar(20),

uage int,active char(1));

第二步,编写备份用的触发器,只有更新或者是插入的时候才触发

以下是引用片段:

alter trigger test3_bak_insert_update

on test3

for insert,update

as

declare @id int

declare @uname varchar(20)

declare @uage int

begin

select @id=id,@uname=uname,@uage=uage from inserted

if @id0

begin

update test3_bak set active='0' where bid=@id

insert into test3_bak(bid,uname,uage,active)

values(@id,@uname,@uage,'1')

end

end

第三步,测试数据:

下面是引用的片段:

insert into test3(uname,uage) values('FLB',20)

insert into test3(uname,uage) values('FLB1',21)

insert into test3(uname,uage) values('FLB2',22)

update test3 set uage=100 where id=27

delete from test3 where id=20

最后,你可自己采用下面的查询踪两个表的数据变化:

以下是引用片段:

关 键 字:MYSQL

篇3:用UML进行有效业务建模

大多数软件开发实践者都知道,UML在对真实世界的现象进行建模时非常优秀,这一特性可以有效帮助分析员和客户进行沟通。

一些希望使用业务建模的团队常常有一些经验性的问题,例如:

什么时候真正需要业务模型?什么时候用例模型独立存在?

我在进行精确的业务建模时我能用哪些UML图形?我如何知道是否用顺序图或者交互图。有例子吗?

业务模型如何涉及到其他模型(如领域模型,用例模型等等)呢?我如何有机地组织这些模型?

很不幸,本文的焦点集中于应用UML进行业务建模的问题,而很少把业务建模和系统建模进行比较。这将使用户和分析员对使用UML进行业务建模的感到灰心。

本文主要通过一个例子讲述它们的关系。这个例子主要用来改进某企业的流程,主要涉及到IT部门、法律顾问、企业架构师、项目经理。

业务用例模型概览

在这个简单的例子中的第一步是完成业务用例模型概览。如图所示,有两个业务主角和两个业务用例。

我们总结业务用例如下:

Prepare Tender:  准备系统说明书的流程。

Select Vendor:     选择卖方的流程。

我们总结业务主角如下:

End User Manager: 公司内的需要自动控制系统的部门。

Vendor Manager:    卖方的管理者。

在这个例子中,得到一个新系统的核心业务目标被精化为两个子目标:

详细说明想得到的系统。

选择并评估候选人。

业务用例规约

这一部分,我们来看看如何描述业务用例,虽然RUP中对业务用例规约有很详细的模版,但我们主要把精力放在基本流和扩展流上。

Prepare Tender的基本流:

用例的目标是确定招标文件,同时可以将招标文件发布给候选卖主。

指定用户代表。

用户代表准备系统规约。

IT部门复审系统规约,并改进它,形成招标文件。

用户代表批准招标文件。

扩展流:

系统规约无效。当IT部门发现需求太含糊,最终用户的管理者必须重新制作需求。那么这个用例从第二步从新开始,如果最终用户管理者不想继续,也可以终止。

系统已存在。如果IT部门发现这个需要的系统和其它部门存在的系统很类似,IT部门就提交给最终用户管理者。如果最终用户管理者希望继续寻找新系统,他必须写出该系统的特色,并重新提交该说明书,回到第二步,如果最终用户管理者不想继续,也可以终止。

招标文件和需求规约冲突。在第四步,最终用户管理者发现招标文件有问题,它将被拒绝,IT部门必须重新做它,用例在第三步继续,

业务用例实现

在这部分,我们从几个方面去实现业务用例。

以工作流为中心

以流程自动化为中心

以信息处理为中心

焦点集中在工作流

我们要精力集中在业务角色的职责上,如图所示,Prepare Tender有三个业务角色:

下面的顺序图描述了Prepare Tender的基本流。

上图中的消息可以映射到每个业务角色的职责(如下图所示)。这个技术非常类似于用例分析。由此可见RUP业务建模的技术是很强大的:相同的技术可用于业务建模和系统建模。

焦点集中在流程自动化

现在我们准备去探索业务主角和业务角色职责,明确什么时候使用业务系统以及如何使用业务系统。在我们的例子中,我们有两个业务系统,如下图所示。

TMS是准备招标和选择卖主的系统。这是一个新系统。

CMS是跟踪合同的系统,已存在。

在RUP中,业务对象建模的指导方针建议可以对“业务系统”定义一个新的泛型图标,在这篇文章中我们将使用“业务角色”图标来表示“业务系统”。将有一个新的图标在新的UML业务建模规范中。

下面的顺序图描述了Prepare Tender基本流的实现,包含了需求的业务系统。

上图中的消息可以映射到业务角色的职责。如下图所示:

从上图中可以得到系统用例,如下图:

焦点集中在信息处理

现在让我们看看业务用例在信息处理上的实现,这就是说,有多少业务实体。经过分析,我们将得到四个业务实体,如下图:

下图是实现Prepare Tender的交互图(侧重于信息处理)。

上面两张图的消息可以映射到每上业务实体的职责,如下图:

下图是上图的一个简化。

结论

软件系统开发出来是为了达到业务目标,可是,用户,分析员,和开发人员常常生活在不同的世界;他们有不同的看法和用不同的行话。小组间的通讯障碍导致在解释各种系统需求时发生很多激烈的争论。具有代表性的一点是,他们的改变不是因为用户改变了想法,而是因为最初的需求需要净化。

来自:tech.it168.com/m/-01-10/200801101004390.shtml

篇4:用ghost进行数据恢复详解

在我们想对硬盘进行分区的时候,通常用到的软件就是Partition Magic,Partition Magic是大家很熟悉的一款软件,但是他也有个弊端,就是误操作率相当高,在合并的过程中往往由于没有对分区的数据进行备份,导致合并后分区中的重要的文件无法被读出,在“我的电脑”中也无法显示。但事实上,文件并没有损坏,是可以恢复回来的,如何恢复呢?ghost就可以做到,

由于Ghost可以将整个硬盘或分区生成一个镜像文件,而GhostExp可以从镜像文件中提取里面的任意文件,因此我们可以通过Ghost.exe和GhostExp.exe这两个工具找回文件。

具体操作如下:

1. 将损坏的分区通过Ghost.exe生成一个镜像文件,保存在其他分区或硬盘中;

2. 在Windows下运行GhostExp.exe,打开刚才生成的镜像文件,可以看见合并前两个分区的文件一个不少地显示出来了;

3. 选中需要恢复的文件,单击鼠标右键,选择“Restore”命令,在弹出的对话框中选择恢复到的位置,再单击“Restore”即可;

4. 重复上述过程,将所有需要的文件全部恢复出来。

篇5:用SQL进行函数查询数据库教程

Oracle 9i提供了很多函数可以用来辅助数据查询,

用SQL进行函数查询数据库教程

。接下来我们介绍常用的函数功能及使用方法。

4.5.1 【ceil】函数

在【命令编辑区】输入“select mgr, mgr/100,ceil(mgr/100) from scott.emp;”,然后单击【执行】按钮,出现如图4.29所示的结果。

【参见光盘文件】:\第4章\4.5\451.sql。

【ceil】函数用法:ceil(n),取大于扔谑值n的最小整数。

4.5.2 【floor】函数

在【命令编辑区】输入“select mgr, mgr/100,floor(mgr/100) from scott.emp;”,然后单击【执行】按钮,出现如图4.30所示的结果。

【参见光盘文件】:\第4章\4.5\452.sql。

【floor】函数用法:floor(n),取小于等于数值n的最大整数。

4.5.3 【mod】函数

在【命令编辑区】输入“select mgr, mod(mgr,1000), mod(mgr,100), mod(mgr,10) from scott.emp;”,然后单击【执行】按钮,出现如图4.31所示的结果。

【参见光盘文件】:\第4章\4.5\453.sql。

【mod】函数用法:mod(m,n),取m整除n后的余数。

4.5.4 【power】函数

在【命令编辑区】输入“select mgr, power(mgr,2),power(mgr,3) from scott.emp;”,然后单击【执行】按钮,出现如图4.32所示的结果。

【参见光盘文件】:\第4章\4.5\454.sql。

【power】函数用法:power(m,n),取m的n次方。

4.5.5 【round】函数

在【命令编辑区】输入“select mgr, round(mgr/100,2),round(mgr/1000,2) from scott.emp;”,然后单击【执行】按钮,出现如图4.33所示的结果。

【参见光盘文件】:\第4章\4.5\455.sql。

【round】函数用法:round(m,n),四舍五入,保留n位。

4.5.6 【sign】函数

在【命令编辑区】输入“select mgr, mgr-7800,sign(mgr-7800) from scott.emp;”,然后单击【执行】按钮,出现如图4.34所示的结果,

【参见光盘文件】:\第4章\4.5\456.sql。

【sign】函数用法:sign(n)。n>0,取1;n=0,取0;n<0,取-1。

4.5.7 【avg】函数

在【命令编辑区】输入“select avg(mgr)平均薪水 from scott.emp;”,然后单击【执行】按钮,出现如图4.35所示的结果。

【参见光盘文件】:\第4章\4.5\457.sql。

【avg】函数用法:avg(字段名),求平均值。要求字段为数值型。

4.5.8 【count】函数

(1)在【命令编辑区】输入“select count(*) 记录总数 from scott.emp;”,然后单击【执行】按钮,出现如图4.36所示的结果。

【参见光盘文件】:\第4章\4.5\458-1.sql。

(2)在【命令编辑区】输入“select count(distinct job ) 工作类别总数 from scott.emp;”,然后单击【执行】按钮,出现如图4.37所示的结果。

【参见光盘文件】:\第4章\4.5\458-2.sql。

【count】函数用法:count(字段名)或count(*),统计总数。

4.5.9 【min】函数

在【命令编辑区】输入“select min(sal) 最少薪水 from scott.emp;”,然后单击【执行】按钮,出现如图4.38所示的结果。

【参见光盘文件】:\第4章\4.5\459.sql。

【min】函数用法:min(字段名),计算数值型字段最小数。

4.5.10 【max】函数

在【命令编辑区】输入“select max(sal) 最高薪水 from scott.emp;”,然后单击【执行】按钮,出现如图4.39所示的结果。

【参见光盘文件】:\第4章\4.5\4510.sql。

【max】函数用法:max(字段名),计算数值型字段最大数。

4.5.11 【sum】函数

在【命令编辑区】输入“select sum(sal) 薪水总和 from scott.emp;”,然后单击【执行】按钮,出现如图4.40所示的结果。

【参见光盘文件】:\第4章\4.5\4511.sql。

【sum】函数用法:sum(字段名),计算数值型字段总和。

通过上面4类查询实例的学习,读者可以举一反三,灵活运用。用SQL进行数据的查询就介绍到这里,下面学习如何录入数据。

篇6:用SQL进行单表查询数据库教程

单表查询是相对多表查询而言的,指从一个数据表中查询数据,

用SQL进行单表查询数据库教程

4.2.1 查询所有的记录

在【命令编辑区】执行输入“select * from scott.emp”,然后单击【执行】按钮,出现如图4.3所示的emp数据表所有记录。

【参见光盘文件】:\第4章\4.2\421.sql。

select * from 数据表,这里的“*”代表数据表中所有的字段。

4.2.2 查询所有记录的某些字段

在【命令编辑区】输入“select empno,ename,job from scott.emp”,然后单击【执行】按钮,将显示emp数据表的empno、ename和job字段,如图4.4所示。

【参见光盘文件】:\第4章\4.2\422.sql。

select 字段名1, 字段名2,…… from 数据表,将显示某些特定的字段,注意这里的字段名之间的逗号是英文状态下的逗号。

4.2.3 查询某些字段不同记录

在图4.4所示的job字段中,可以发现有相同的数据,为了查询有多少种不同的job,在【命令编辑区】输入“select distinct job from scott.emp”,然后单击【执行】按钮,出现如图4.5所示的结果。

【参见光盘文件】:\第4章\4.2\423.sql。

select distinct 字段名 from 数据表,这里的“distinct”保留字指在显示时去除相同的记录,与之对应的是“all”将保留相同的记录,默认为“all”。

4.2.4 单条件的查询

(1)在【命令编辑区】输入“select empno,ename,job from scott.emp where job=’MANAGER’”,然后单击【执行】按钮,出现如图4.6所示的字符型字段条件查询的结果,查询的是job为MANAGER的记录。

【参见光盘文件】:\第4章\4.2\424-1.sql。

(2)在【命令编辑区】输入“select empno,ename,sal from scott.emp where sal<=2500”,然后单击【执行】按钮,出现如图4.7所示的数字型字段条件查询的结果,查询的是满足sal小于等于2500的记录。

【参见光盘文件】:\第4章\4.2\424-2.sql。

where可以指定查询条件,如果是指定字符型字段查询条件,形式为字段名 运算符 '字符串';如果是指定数字型字段查询条件,形式为字段名 运算符 '字符串'。 单条件查询使用的比较运算符如表4.1所示。

【参见光盘文件】:\第4章\4.2\table41.sql。

表4.1 比较运算符名称实例=(等于)select * from scott.emp where job=’MANAGER’;select * from scott.emp where sal=1100;!= (不等于)select * from scott.emp where job!=’MANAGER’;select * from scott.emp where sal!=1100;^=(不等于)select * from scott.emp where job^=’MANAGER’;select * from scott.emp where sal^=1100;(不等于)select * from scott.emp where job’MANAGER’;select * from scott.emp where sal1100;<(小于)select * from scott.emp where sal<;select * from scott.emp where job<’MANAGER’;>(大于)select * from scott.emp where sal>2000;select * from scott.emp where job>’MANAGER’;<=(小于等于)select * from scott.emp where sal<=2000;select * from scott.emp where job<=’MANAGER’;>=(大于等于)select * from scott.emp where sal>=2000;select * from scott.emp where job>=’MANAGER’;in(列表)select * from scott.emp where sal in (2000,1000,3000);select * from scott.emp where job in (’MANAGER’,’CLERK’);not in(不在列表)select * from scott.emp where sal not in (2000,1000,3000);select * from scott.emp where job not in (’MANAGER’,’CLERK’);between(介于之间)select * from scott.emp where sal between 2000 and 3000;select * from scott.emp where job between ’MANAGER’ and ’CLERK’;not between (不介于之间)select * from scott.emp where sal not between 2000 and 3000;select * from scott.emp where job not between ’MANAGER’ and ’CLERK’;like(模式匹配)select * from scott.emp where job like ’M%’;select * from scott.emp where job like ’M__’;not like (模式不匹配)select * from scott.emp where job not like ’M%’;select * from scott.emp where job not like ’M__’;Is null (是否为空)select * from scott.emp where sal is null;select * from scott.emp where job is null;is not null(是否为空)select * from scott.emp where sal is not null;select * from scott.emp where job is not null;

like和not like适合字符型字段的查询,%代表任意长度的字符串,_下划线代表一个任意的字符,

like ‘m%’ 代表m开头的任意长度的字符串,like ‘m__’ 代表m开头的长度为3的字符串。

4.2.5 组合条件的查询

(1)在【命令编辑区】输入“select empno,ename,job from scott.emp where job>=’CLERK’ and sal<=2000”,然后单击【执行】按钮,出现如图4.8所示的逻辑与组合查询的结果。

【参见光盘文件】:\第4章\4.2\425-1.sql。

(2)在【命令编辑区】输入“select empno,ename,job from scott.emp where job>=’CLERK’ or sal<=2000”,然后单击【执行】按钮,出现如图4.9所示的逻辑或组合查询的结果。

【参见光盘文件】:\第4章\4.2\425-2.sql。

(3)在【命令编辑区】输入“select empno,ename,job from scott.emp where not job=’CLERK’”,然后单击【执行】按钮,出现如图4.10所示的逻辑非组合查询的结果。

【参见光盘文件】:\第4章\4.2\425-3.sql。

“not job=’CLERK’”等价于“job’CLERK’”。

组合条件中使用的逻辑比较符如表4.2所示。

【参见光盘文件】:\第4章\4.2\table42.sql。

表4.2 逻辑比较符

名称实例and(与)select * from scott.emp where job=’MANAGER’ and sal2000;or (或)select * from scott.emp where job!=’MANAGER’ or sal2000;not(非)select * from scott.emp where not job>=’MANAGER’;

4.2.6 排序查询

在【命令编辑区】输入“select empno,ename,job from scott.emp where job<=’CLERK’ order by job asc,sal desc”,然后单击【执行】按钮,出现如图4.11所示的排序查询的结果。

【参见光盘文件】:\第4章\4.2\426.sql。

order by 可以指定查询结果如何排序,形式为字段名 排序关键词;asc代表升序排列,desc代表降序排列,多个排序字段之间通过逗号分割。若有where查询条件,order by要放在where语句后面。

4.2.7 分组查询

分组查询是指将查询结果按照字段分组。

(1)在【命令编辑区】输入“select empno,ename,job,sal from scott.emp group by job,empno,ename,sal having sal<=2000”,然后单击【执行】按钮,出现如图4.12所示的分组查询的结果。

【参见光盘文件】:\第4章\4.2\427-1.sql。

(2)在【命令编辑区】输入“select empno,ename,job,sal from scott.emp where sal<=2000 group by job,empno,ename,sal”,然后单击【执行】按钮,出现如图4.13所示的分组查询的结果。

【参见光盘文件】:\第4章\4.2\427-2.sql。

where检查每条记录是否符合条件,having是检查分组后的各组是否满足条件。having语句只能配合group by语句使用,没有group by时不能使用having,但可以使用where。

4.2.8 字段运算查询

可以利用几种基本的算术运算符来查询数据。

常见的+(加)、-(减)、*(乘)、/(除)4种算术运算都可以用来查询数据。

在【命令编辑区】输入“select empno,ename,sal,mgr,sal+mgr from scott.emp”,然后单击【执行】按钮,出现如图4.14所示的结果。

【参见光盘文件】:\第4章\4.2\428.sql。

利用算术运算符仅仅适合多个数值型字段或字段与数字之间的运算。

4.2.9 变换查询显示

在【命令编辑区】输入“select empno 编号,ename 姓名,job 工作,sal 薪水 from scott.emp”,然后单击【执行】按钮,出现如图4.15所示的结果,可以将默认的字段名以设定的名称显示。

【参见光盘文件】:\第4章\4.2\429.sql。

以上我们学习了对单个数据表的查询语句。将上面这些基本的实例经过组合,就可以完成基本的日常数据查询任务,接下来进一步学习多表查询。

篇7:用VB存取SQL Server中的图像数据

本文介绍MIS SQL Server对图像数据的存储机制和存取方法,针对VB开发工具,介绍了一种通过ADO Field 对象的GetChunk 方法和AppendChunk 方法来存取MIS SQL Server中的图像数据的方法。

在一个完善的医院信息MIS中,图像数据的存取是必不可少的,比如X光片、CT像片的保存。一方面,这些图像数据在远程诊疗为准确诊断病情提供了重要的依据,另一方面,也为快速查阅病人资料提供了基本条件。图像数据的存取在其它应用系统如GIS中也有广泛的应用。

1、SQL Server中图像数据的存储机制

在MIS SQL Server中,对于小于8000个字节的图像数据可以用二进制型(binary、varbinary)来表示。但通常要保存的一些医学影像图片都会大于 8000个字节。SQL Server提供了一种机制,能存储每行大到2GB的二进制对象(BLOB),这类对象可包括image、text和ntext三种数据类型。Image数据类型存储的是二进制数据,最大长度是231-1 (2,147,483,647)个字节。

BLOB数据在MIS SQL Server系统中的存储方式不同于普通的数据类型,对于普通类型的数据系统直接在用户定义的字段上存储数据值,而对于BLOB类型数据,系统开辟新的存储页面来存放这些数据,表中BLOB类型数据字段存放的仅是一个16个字节的指针,该指针指向存放该条记录的BLOB数据的页面。

2、SQL Server中图像数据的存取

在MIS SQL Server中,当数据小于8000个字节时,可以用普通的SQL操纵语句(SELECT、INSERT、UPDATE、DELETE)来完成对字段的操纵,当数据大于8000个字节时,SQL提供了WRITETEXT 、READTEXT和UPDATETEXT这三个函数来读取和修改数据。这三个函数的使用方法为:

(1) WRITETEXT {table.column text_ptr}[WITH LOG] {data}

table.column为表中的字段,text_ptr为一个16个字节的指针,data为要写的数据值。可选参数WITH LOG表示是否要写入日志文件中。

例:

DECLARE @ptrval binary(16) --指针

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 0101001

WRITETEXT zy_ct.img_ct @ptrval 0x024324142342134214213421421454353452341

(2) READTEXT {table.column text_ptr offset size} [HOLDLOCK]

table.column为表中的字段,text_ptr为一个16个字节的指针,offset 为偏移量,即从第几个字节开始读数据,size为要读的字节数,HOLDLOCK 为在读数据中是否充许其他用户修改该数据。

例:

DECLARE @ptrval varbinary(16)

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001

READTEXT zy_ct.img_ct @ptrval 1 25

(3) UPDATETEXT

{table_name.dest_column_name dest_text_ptr}

{NULL|insert_offset}{ NULL | delete_length}

[WITH LOG][ inserted_data|

{table_name.src_column_name src_text_ptr}]

table_name.dest_column_name 为要修改的text, ntext, 或 image字段;dest_text_ptr为指向其的指针;insert_offset为偏移量,对于text和image为从第几开始字节开始写,对于ntext为从第几个字符(双字节)开始写;delete_length为从insert_offset开始删除delete_length长度的字节(符),为0时不删除,为NULL时为删除从insert_offset开始到结束的所有数据。要插入的数据为 inserted_data为,也可是表table_name的src_column_name字段中指针 src_text_ptr所指数据。

例:

DECLARE @ptrval binary(16)

SELECT @ptrval = TEXTPTR(img_ct) FROM zy_ct WHERE id_ct = 20010101001

UPDATETEXT zy_ct.img_ct @ptrval 16 0x54345

可以看出,这三个函数的使用比较复杂,虽然可以通过生成存贮过程来调用执行,但有一个缺陷是在读取数据时,READTEXT函数读取的数据无法直接传递回前端应用程序。

3、VB 6.0中图像数据的存取

VB 6.0 的ADO Field对象提供了GetChunk方法和AppendChunk方法来存取BLOB数据,这两个函数实质是通过API调用WRITETEXT 、READTEXT和UPDATETEXT这三个函数,简化了调用的方法。

(1)GetChunk和AppendChunk方法介绍:

GetChunk方法检索其部分或全部长二进制或字符数据。GetChunk 调用返回的数据将赋给“变量”。如果 Size 大于剩余的数据,则 GetChunk 仅返回剩余的数据而无需用空白填充“变量”。如果字段为空,则 GetChunk 方法返回 Null。每个后续的 GetChunk 调用将检索从前一次 GetChunk 调用停止处开始的数据。但是,如果从一个字段检索数据然后在当前记录中设置或读取另一个字段的值,ADO 将认为已从第一个字段中检索出数据。如果在第一个字段上再次调用 GetChunk 方法,ADO 将把调用解释为新的 GetChunk 操作并从记录的起始处开始读取。Field 对象的第一个 AppendChunk 调用将数据写入字段,覆盖所有现有的数据,随后的 AppendChunk 调用则添加到现有数据。

由于系统资源总是有限的,如果一次读(存)取大量数据,可能会引起服务器、客户机死机或是服务器的性能大大下降,因此使用这两个函数时,要将图像数据进行分段读写。

(2)程序实现:

程序一:写数据函数:

Public Function AppendBlobFromFile

(blobColumn As ADODB.Field, ByVal FileName) As Boolean

Dim FileNumber As Integer '文件号

Dim DataLen As Long '文件长度

Dim Chunks As Long '数据块数

Dim ChunkAry As Byte '数据块数组

Dim ChunkSize As Long '数据块大小

Dim Fragment As Long '零碎数据大小

Dim lngI As Long '计数器

On Error GoTo ErrorHandle

AppendBlobFromFile = False

ChunkSize = 2048 '限制每次读取的块大小为 2K

FileNumber = FreeFile '产生随机的文件号

Open FileName For Binary Access Read As FileNumber '打开图像文件

DataLen = LOF(FileNumber) '获得文件长度

If IsNull(blobColumn) Then Exit Function

If DataLen = 0 Then '文件长度为0

Close FileNumber

AppendBlobFromFile = True

Exit Function

End If

Chunks = DataLen \ChunkSize '数据块的个数

Fragment = DataLen Mod ChunkSize

If Fragment >0 Then '先写零碎数据

ReDim ChunkAry(Fragment - 1)

Get FileNumber, , ChunkAry() '读出文件

blobColumn.AppendChunk ChunkAry '调用AppendChunk函数写数据

End If

ReDim ChunkAry(ChunkSize - 1) '为数据块开辟空间

For lngI = 1 To Chunks '循环读出所有数据块

Get FileNumber, , ChunkAry() '读出一块数据

blobColumn.AppendChunk ChunkAry '在数据库中增加数据块

Next lngI

Close FileNumber '关闭文件

AppendBlobFromFile = True

Exit Function

ErrorHandle:

AppendBlobFromFile = False

MsgBox Err.Description, vbCritical, “写图像数据出错!”

End Function

程序二:读数据函数:

Public Function ReadbolbToFile

(blobColumn As ADODB.Field, ByVal FileName) As Boolean

Dim FileNumber As Integer '文件号

Dim DataLen As Long '文件长度

Dim Chunks As Long '数据块数

Dim ChunkAry() As Byte '数据块数组

Dim ChunkSize As Long '数据块大小

Dim Fragment As Long '零碎数据大小

Dim lngI As Long '计数器

On Error GoTo ErrorHandle

ReadbolbToFile= False

ChunkSize = 2048 '定义块大小为 2K

If IsNull(blobColumn) Then Exit Function

DataLen = blobColumn.ActualSize '获得图像大小

If DataLen < 8 Then Exit Function '图像大小小于8字节时认为不是图像信息

FileNumber = FreeFile '产生随机的文件号

Open FileName For Binary Access Write As FileNumber '打开存放图像数据文件

Chunks = DataLen \ChunkSize '数据块数

Fragment = DataLen Mod ChunkSize '零碎数据

If Fragment >0 Then '有零碎数据,则先读该数据

ReDim ChunkAry(Fragment - 1)

ChunkAry = blobColumn.GetChunk(Fragment)

Put FileNumber, , ChunkAry '写入文件

End If

ReDim ChunkAry(ChunkSize - 1) '为数据块重新开辟空间

For lngI = 1 To Chunks '­循环读出所有块

ChunkAry = blobColumn.GetChunk(ChunkSize) '在数据库中连续读数据块

Put FileNumber, , ChunkAry() '将数据块写入文件中

Next lngI

Close FileNumber '关闭文件

ReadbolbToFile= True

Exit Function

ErrorHandle:

ReadbolbToFile= False

MsgBox Err.Description, vbCritical, “读图像数据出错!”

End Function

当BLOB类型的字段为空时,调用AppendChunk或 GetChunk函数将出错,

此时如果想给该字段插入图像数据,应该先使用 Update语句给该字段赋初值如0x0,以便数据库系统为该字段分配一个页面地址来存放BLOB数据。

4、总结

Microsoft SQL Server为保存大二进制数据提供了存储平台,Visual Basic 6.0为存取这种数据提供了灵活的接口。本文介绍的用VB接口存取 MIS SQL Server中大二进制数据的方法,不但适用于图像文件,同样适用于其它类型的文件。该方法应用于医院管理系统的图像存取中,在存取速度、对系统的性能影响等方面都取了满意的效果。

篇8:如何对SQL Server中的XML数据进行insert、update、delete .

SQL Server /增加了对XML数据的支持,同时也新增了几种操作XML的方法,本文主要以SQL Server 2008为例介绍如何对XML数据进行insert、update、delete,

SQL Server中新增加了XML.Modify()方法,分别为xml.modify(insert),xml.modify(delete),xml.modify(replace)对应XML的插入,删除和修改操作。

本文以下面XML为例,对三种DML进行说明:

declare @XMLVar xml = '

Windows Step By Step

Bill Zack

49.99

Developing ADO .NET

Andrew Brust

39.93

Windows Cluster Server

Stephen Forte

59.99

'

1.XML.Modify(Insert)语句介绍

A.利用as first,at last,before,after四个参数将元素插入指定的位置

set @XMLVar.modify(

'insert as first into (/catalog[1]/book[1])')

set @XMLVar.modify(

'insert as last into (/catalog[1]/book[1])')

set @XMLVar.modify(

'insert before (/catalog[1]/book[1]/author[1])')

set @XMLVar.modify(

'insert after (/catalog[1]/book[1]/author[1])')

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2:

3: Windows Step By Step

4:

5: Bill Zack

6:

7:

49.99

8:

9:

B.将多个元素插入文档中

--方法一:利用变量进行插入

DECLARE @newFeatures xml;

SET @newFeatures = N';

one element

second element'

SET @XMLVar.modify(' )

insert sql:variable(“@newFeatures”)

into (/catalog[1]/book[1])'

--方法二:直接插入

set @XMLVar.modify(')

insert (one element,second element)

into (/catalog[1]/book[1]/author[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2: Windows Step By Step

3: Bill Zack

4: one element

5: second element

6:

7:

49.99

8: one element

9: second element

10:

C.将属性插入文档中

--使用变量插入

declare @var nvarchar(10) = '变量插入'

set @XMLVar.modify(

'insert (attribute var {sql:variable(“@var”)}))

into (/catalog[1]/book[1])'

--直接插入

set @XMLVar.modify(

'insert (attribute name {“直接插入”}))

into (/catalog[1]/book[1]/title[1])'

--多值插入

set @XMLVar.modify(

'insert (attribute Id {“多值插入1”},attribute name {“多值插入2”}) )

into (/catalog[1]/book[1]/author[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2: Windows Step By Step

3: Bill Zack

4:

49.99

5:

D.插入文本节点

set @XMLVar.modify(

'insert text{“at first”} as first)

into (/catalog[1]/book[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2: at first

3: Windows Step By Step

4: Bill Zack

5:

49.99

6:

注意:插入本文同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

E.插入注释节点

set @XMLVar.modify(

'insert )

before (/catalog[1]/book[1]/title[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2:

3: Windows Step By Step

4: Bill Zack

5:

49.99

6:

注意插入注释节点同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

F.插入处理指令

set @XMLVar.modify(

'insert

before (/catalog[1]/book[1]/title[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');结果集为:

1:

2:

3: Windows Step By Step

4: Bill Zack

5:

49.99

6:

注意插入处理指令同样具体 as first,as last,before,after四种选项,可以参考A中的使用方法

G.根据 if 条件语句进行插入

set @XMLVar.modify(

'insert )

if (/catalog[1]/book[1]/title[2]) then

text{“this is a 1 step”}

else ( text{“this is a 2 step”} )

into (/catalog[1]/book[1]/price[1])'

SELECT @XMLVar.query('/catalog[1]/book[1]');

结果集为:

1:

2: Windows Step By Step

3: Bill Zack

4:

49.99this is a 2 step

5:

2.XML.Modify(delete)语句介绍

--删除属性

set @XMLVar.modify('delete /catalog[1]/book[1]/@category')

--删除节点

set @XMLVar.modify('delete /catalog[1]/book[1]/title[1]')

--删除内容

set @XMLVar.modify('delete /catalog[1]/book[1]/author[1]/text()')

--全部删除

set @XMLVar.modify('delete /catalog[1]/book[2]')

SELECT @XMLVar.query('/catalog[1]');

结果集为:

1:

2:

3:

4:

49.99

5:

6:

7: Windows Cluster Server

8: Stephen Forte

9:

59.99

10:

11:

3.XML.Modify(replace)语句介绍

--替换属性

set @XMLVar.modify('replace value of(/catalog[1]/book[1]/@category))

with (“替换属性”)'

--替换内容

set @XMLVar.modify('replace value of(/catalog[1]/book[1]/author[1]/text()[1]))

with(“替换内容”)'

--条件替换

set @XMLVar.modify('replace value of (/catalog[1]/book[2]/@category))

with(

if(count(/catalog[1]/book)>4) then

“条件替换1”

else

“条件替换2”)'

SELECT @XMLVar.query('/catalog[1]');

结果集为:

1:

2: 

3: Windows Step By Step

4: 替换内容

5:

49.99

6:

7: 

8: Developing ADO .NET

9: Andrew Brust

10:

39.93

11:

12: 

13: Windows Cluster Server

14: Stephen Forte

15:

59.99

16:

17:

作者“cnming”

篇9:用ROLLUP进行分类数据统计(二)综合教程

我们介绍了ms sql server中的roll up语句,下面开始介绍如何用datagrid结合rollup语句来进行分类统计。

我们要达到的效果是这样的:

首先,应先将数据库中的产品数据按照所属的不同的目录列举出来,这其中要用到一些技巧.这里先用SQL语句,从数据库读取product表的数据,之后放到dataset的默认datatable中去,然后检查每一个产品所属的类别,如果发现某一个产品的类别和前一条记录中产品所属的类别不一样的话,那么就可以肯定当前产品是属于一个新的分类了,就可以插入新的行,并且加以修饰,成为分类标题,同时将roll up的统计结果显示在相应的位置就可以了。我们先来看page_load部分的代码

Sub Page_Load(Sender As Object, E As EventArgs) Handles MyBase.Load

' TODO: Update the ConnectionString and CommandText values for your application

dim ConnectionString as string = “server=localhost;database=northwind;UID=sa”

Dim CommandText As String = “Select CASE WHEN (Grouping(CategoryName)=1) THEN ” & _

“'MainTotal' ELSE categoryname END AS CategoryName, ”

CommandText &= “ CASE WHEN (Grouping(ProductName)=1) THEN 'SubTotal' ELSE ” & _

“Productname END AS ProductName,”

CommandText &= “ Sum(UnitPrice) as unitprice, ”

CommandText &= “ Sum(UnitsinStock) as UnitsinStock ”

CommandText &= “ from Products INNER JOIN Categories On Products.categoryID = ” & _

“ Categories.CategoryID”

CommandText &= “ Group By Categoryname, ProductName WITh ROLLUP ”

Dim myConnection As New SqlConnection(ConnectionString)

Dim myCommand As New SqlDataAdapter(CommandText, myConnection)

Dim ds As New DataSet

myCommand.Fill(ds)

Dim curCat As String ‘指示当前记录中产品所属的类别

Dim prevCat As String ‘

关 键 字:SQLServer

篇10:用ROLLUP进行分类数据统计(一)综合教程

通常,我们在写web应用程序中,会经常用到分类数据统计的功能,在一个电子商务网站中,我们往往对销售的每类商品的销售额,销售的数量要进行分类统计。那么,在asp.net中,我们如何用datagrid,一方面显示数据库中的数据,一方面又能按类别对数据进行分类统计呢?方法应该有很多种,但在这里,想介绍一种容易被人遗忘的方法,那就是使用MS SQL SERVER中的roll up语句了。

让我们先来介绍下ms sql server中的roll up语句。Roll up语句,在对统计的数据既要进行分类求和,又要求其总和时,是十分有用的。Roll up语句必须配合group by使用,举个例子,比如在northwind数据库中,为了返回同一目录下的产品总价格,和库存量,可以使用如下sql 语句:

SELECT

CategoryName,

SUM(UnitPrice) as UnitPrice,

SUM(UnitsinStock) as UnitsinStock

FROM Products

INNER JOIN Categories On

Products.CategoryID = Categories.CategoryID

GROUP BY CategoryName

返回的结果如下

而如果想既列出分类中所有产品,又能分类统计出每个分类的产品,价格统计总数,那么roll up就大有用武之地了。我们想达到的效果可以用下图表示:

请注意上表中黄色的部分,比如,

表示meat/poultry这个分类中的产品总价格和数量,这就达到了分类统计的目的,最后一行

表示所有分类中产品的总价格和总的数量。可以看出,roll up的实质就是按列,既对分类求和又求所有分类的总和,但要注意一点,roll up在做分类统计时,会在某些字段插入空值,比如,在

中,rollup在做分类统计时,首先是会以下面的形式出现

那么如何将这些null值替换掉呢,可以使用下面的语句:

SELECT

CASE

WHEN (Grouping(CategoryName)=1) THEN 'MainTotal'

ELSE CategoryName

END AS CategoryName,

CASE

WHEN (Grouping(ProductName)=1) THEN 'SubTotal'

ELSE Productname

END AS ProductName,

Sum(UnitPrice) as UnitPrice,

Sum(UnitsinStock) as UnitsInStock

FROM Products

INNER JOIN Categories On

Products.CategoryID = Categories.CategoryID

GROUP BY CategoryName, Produ

关 键 字:SQLServer

【SQL用XML数据类型进行数据建模】相关文章:

1.用“幸福”进行造句

2.“用数据说话”行吗?

3.正确理解SQL Server四类数据仓库建模方法综合教程

4.用假设检验对自动站和人工站数据进行检验分析

5.用从此一词进行造句

6.用英语如何进行面试自我介绍?

7.用google来进行“渗透测试”

8.进行体育运动用英文怎么表达?

9.在金山WPS表格中进行快速查找数据

10.全国公共英语考试语法——用助动词进行强调

下载word文档
《SQL用XML数据类型进行数据建模.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度: 评级1星 评级2星 评级3星 评级4星 评级5星
点击下载文档

文档为doc格式

SQL用XML数据类型进行数据建模相关文章
最新推荐
猜你喜欢
  • 返回顶部