??xml version="1.0" encoding="utf-8" standalone="yes"?> 备䆾全部的库
]]>
mysqldump db_name > /path/name.sql -uroot -p
如果数据库太大,压羃导出
mysqldump db_name | gzip > /path/name.sql -u root -p
mysqldump --all-databases > /path/name.sql -u root -p
mysqldump --all-databases | gzip > /path/name.gz -uroot -p
备䆾一个单独或者几个表
mysqldump db_name tab_name > /path/sqlname.sql -u root -p
恢复数据 导入数据
mysql db_name < backup-file.sql -u root -p
有一U用mysql db_name < backup-file.sql -u root -p
W二U方法:(x)
mysql -u root -p
use db_name
. /path/dbname.sql
q种Ҏ(gu)保险点,因ؓ(f)有时我用 db_name < dbname.sql有问?
用第二种Ҏ(gu)可以?
………………………………………………………?
dmysql用户mysqlname 密码为password Q赋予dbname数据库所有权?
mysql> grant all on dbname.* to mysqlname@localhost identified by 'password';
mysql > grant select,insert,update,delete,create,drop on 数据库名.* to 用户(新徏)@localhost identified by '密码';
或者直接修改mysql?
mysql > insert into user(host,user,password) values('%','user_name',password("you password"));
mysql > set password for user_name=password("you_password")
以上两种必须q行重蝲授权?./scripts/mysql_install_db)
或者在shell环境?
mysqladmin -u root password "you password"
]]>
1. ORACLE
SELECT * FROM TABLE1 WHERE ROWNUM<=N
2. INFORMIX
SELECT FIRST N * FROM TABLE1
3. DB2
SELECT * ROW_NUMBER() OVER(ORDER BY COL1 DESC) AS ROWNUM WHERE ROWNUM<=N
DB2
SELECT COLUMN FROM TABLE FETCH FIRST N ROWS ONLY
4. SQL SERVER
SELECT TOP N * FROM TABLE1
5. SYBASE
SELECT TOP N * FROM TABLE1
]]>
那在查询或是其实操作中,如果只关闭ConnectionQ不作ResultSet ?Statement 的关闭的话,对系l性能是否?x)有影响呢。或者是其实斚w的不良媄响?BR>
如果你不使用q接池,那么没有什么问题,一旦Connection关闭Q数据库物理q接p释放Q所有相关Java资源也可以被GC回收了?
但是如果你用连接池Q那么请注意QConnection关闭q不是物理关闭,只是归还q接池,所以PreparedStatement和ResultSet都被持有Qƈ且实际占用相关的数据库的游标资源Q在q种情况下,只要长期q行Q往往׃(x)报“游标超出数据库允许的最大值”的错误Q导致程序无法正常访问数据库?BR>
补充Q其实这个要看你用的是什么数据库Q然后决定了你的JDBCQ然后呢Q决定了实现q个JDBC的方法,然后呢就军_了问题?
关闭?BR>
不用连接池的情况下,如果你直接关闭连接话,对应的Statement,ResultSet对象都应该由Driver Vendor来帮你关?即由他来q行资源的释?q个是由JDBC3.0规范中提到的.因ؓ(f)有些数据库资源可能属于GC不能释放的范?
对于q接池的实现而言,有时间我看看Oracle和Postgres的实现再下定论吧.但是我认为出C面的情况应该理解成ؓ(f)q接池vendor的一U没有按规范来实现的问题.如果用数据库自己实现的连接池应该不会(x)有这L(fng)情况出现.
使用q接池时也应该会(x)关闭PreparedStatement和ResultSetQ看qApache的DBCPQ它是会(x)关的Q不知道其他q接池是怎么L(fng)。实际上Q用不使用q接池应该对开发者透明Q都应该遵@Jdbc规范Q从q个角度Q连接池如果没有实现关闭功能应该是有问题的?/SPAN>
]]>
数据库物理设计包括:(x)表设计,视图设计Q存储过E设计,用户自定义函数设计等{?/SPAN>
1?SPAN style="FONT: 7pt 'Times New Roman'"> 表设计命名规范:(x)表?/SPAN>t开头最好能表Ҏ(gu)属性分cdƈ作好~号?/SPAN>
如:(x)~码表可写ؓ(f)tBM001Something t开_(d)BMZ务类型,001cd中的W几个表something是表的名U注释?/SPAN>
2?SPAN style="FONT: 7pt 'Times New Roman'"> 视图设计命名规范Q视图设计过E中使用v开_(d)视图命名以制作视囄主表为准或是以视囄实现功能为准?/SPAN>
如:(x)上述tBM001Something Z表制作的视图 可取?/SPAN>vBM001Something
或?/SPAN>vGetSomeThingInfo{?/SPAN>
3?/SPAN>存储q程命名规范Q用戯定义存储q程使用p开头以其实现功能命?/SPAN>,
如:(x)pGetSomethingInfo
4?SPAN style="FONT: 7pt 'Times New Roman'">
存储q程命名规范Q用戯定义存储q程使用f开头以其实现功能命?/SPAN>,
如:(x)fGetSomethingInfo
此外在制作视囑֭储过E用戯定义函数q程中,注意写好注释?/SPAN>
注释内容包括Q名Uͼ作用Q调用,使用表,更新记录Q设计思\Q入口参?/SPAN>
/*========================================================
存储q程名称Q?/SPAN>pro_tXT005TraceLeaderSearch
?/SPAN> 用:(x)生成日志中资源更新情늻计分?/SPAN>
调用存储q程Q?/SPAN>pro_tXT005TraceLeaderSearch
使用表:(x) t BM001Something。。。。。?/SPAN>
更新记录Q?/SPAN>1?/SPAN> cc
2?/SPAN> cc
设计思\Q算法描q?/SPAN>
?/SPAN> ?/SPAN> ?/SPAN> 敎ͼ(x) @startDate 开始日期,@endDate l束旉
--=========================================================*/
在SQL Server 2000中,标准的T-SQL SELECT语句包括F(xin)OR XML子句Q它以XML文形式q回一个查询结果。新的FOR XML子句有三U模式——RAWQAUTOQ和EXPLICITQ每个都能对XML文格式提供附加标准的控制?/P>
下面首先介绍“FOR XML”的使用Ҏ(gu)?/P>
Z从SQL Server提取XML格式的数据,T-SQL中加入了一个FOR XML命o(h)。在查询命o(h)中用FOR XML命o(h)使得查询l果以XML格式出现。FOR XML命o(h)有三U模式:(x)RAWQAUTO和EXPLICIT。图1所昄的SQL命o(h)讉KSQL Server提供的PubsCZ数据库。有关Pubs数据库的更多信息Q请参见MSDN说明。如果我们依ơ指定该SQL命o(h)的模式ؓ(f)三种允许的模式之一Q就可以得到各种模式所支持的不同XML输出?
【图1 ?/P>
SELECT store.stor_id as Id, stor_name as Name, sale.ord_num as OrderNo,sale.qty as Qty FROM stores store inner join sales sale on store.stor_id = sale.stor_id ORDER BY stor_name FOR XML Q模式> |
该查询命令所生成的结果包含所有销售记录及其对应的商店Q结果以商店名称的字母升序排列。查询的最后加上了FOR XML命o(h)以及具体的模式,比如FOR XML RAW?
理想情况下,SQL命o(h)所生成的XML文应具有如下结构:(x)
QStoresQ?/P> QStore Id=&single;&single; Name=&single;&single;Q?/P> Q?Sale OrderNo=&single;&single; Qty=&single;&single;Q?/P> Q?StoreQ?/P> Q?StoresQ?/P> |
下面我们来看看具体的处理Ҏ(gu)?
RAW模式
下面是指定RAW模式时结果XML文档的一个片断?/P>
查询l果集中每一个记录包含唯一的元素<rowQ。由于我们无法控制元素名字和文l构Q因此这U模式不是很有用。RAW模式所生成的文结构与我们所希望的不W,而且它的用途也非常有限?
AUTO模式
下面是指定AUTO模式时结果文的一个片断:(x)
可以看到Q<StroeQ和QSaleQ两个元素是?子关p,形成了我们所希望的层ơ结构。这U节点关pȝ查询中表的声明次序决定,后声明的表成为前声明表的孩子?
再参考图1Q我们可以看出查询命令所指定的别名决定了XML文中的名字。根据这一点,我们可以控制XML文档元素、属性的名字Q得这些名字符合我们所要求的命名惯例?
可见AUTO模式能够创徏出我们所需要的XML文。不q它存在以下~点Q?
虽然可以得到层次l构Q但q种层次l构是线性的Q即每个父节点只能有一个子节点Q反之亦然?
通过别名指定元素名字不太方便Q而且有时候会(x)影响查询命o(h)本n的可L?
无法在文中同时生成元素和属性。要么全部是元素Q通过ELEMENTS关键词指定)Q要么全部是属性(默认Q?EXPLICIT模式解决了上qC?
EXPLICIT模式
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文所描述的数据,而且q包含描qXML文档l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文档层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文档和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文档的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文只能用EXPLICIT模式生成Q?
l果XML文中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文所描述的数据,而且q包含描qXML文档l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文档和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文档中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文只能用EXPLICIT模式生成Q?
l果XML文档中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文档。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文所描述的数据,而且q包含描qXML文l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文档内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文档只能用EXPLICIT模式生成Q?
l果XML文档中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文档所描述的数据,而且q包含描qXML文l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文档所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文档层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文档内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文档l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文只能用EXPLICIT模式生成Q?
l果XML文中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文所描述的数据,而且q包含描qXML文l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文档旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文档层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文档中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文只能用EXPLICIT模式生成Q?
l果XML文中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
EXPLICIT模式比较复杂Q我们将用另外一U方法来表达?所昄的查询。这U方法得我们能够完全地控制查询所生成的XML文档。首先我们将介绍如何改用EXPLICIT模式~写?所昄的查询,然后看看q种Ҏ(gu)如何赋予我们q远过AUTO模式的能力?
下面是图1查询用EXPLICIT模式表达的代码:(x)
【图2 ?/P>
--商店数据 SELECT 1 as Tag, NULL as Parent, s.stor_id as [store!1!Id], s.stor_name as [store!1!Name], NULL as[sale!2!OrderNo], NULL as [sale!2!Qty] FROM stores s UNION ALL -- 销售数?BR>SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty FROM stores s, sales sa WHERE s.stor_id = sa.stor_id ORDER BY [store!1!name] FOR XML EXPLICIT |
q个查询初看h有点复杂Q其实它只是把不同的数据集(卌里的Store和SaleQ分解到了独立的SELECT语句里,然后再用UNION ALL操作W连l成一个查询?
我们之所以要把查询写成上面的形式Q是Z让查询结果不仅包含XML文所描述的数据,而且q包含描qXML文l构的元数据。上q查询所生成的表UCؓ(f)Universal表,sqlxml.dll生成XML文旉要这U格式。Universal表对于编写代码的人来说是透明的,但了解这个表q是很有意义的,它将有助于代码的开发和调试。下面是Universal表的一个例子:(x)
Tag Parent store!1!id store!1!name sale!2!orderno sale!2!qty 1 NULL 7066 Barnum&single;s NULL NULL 2 1 7066 Barnum&single;s A297650 50 2 1 7066 Barnum&single;s QA7442 375 1 NULL 8042 Bookbeat NULL NULL 2 1 8042 Bookbeat 423LL9 2215 |
Universal表和EXPLICIT模式查询的元数据部分都以U色表示Q黑色表C数据。比较查询和表就可以扑ևsqlxml.dll生成XML文档所需要的元素。我们来仔细地分析一下它们描q的是什么?
Tag和Parent列是XML文层次l构斚w的信息,我们可以认ؓ(f)?中的每个SELECT语句代表了一个XML节点Q而Tag和Parent列让我们指定节点在文层ơ结构中的位|。如果在W二个SELECT语句中指定Tag?、指定Parent?Q就表示些数据加上了一个gؓ(f)2的标{,而这些数据的父亲是那些标{ؓ(f)1的数据(即第一个SELECT语句Q。这׃得我们能够构造出QStoreQ和QSaleQ之间的?子关p,而且正如你可能猜惛_的,它得我们可以生成Q意合法的XML文档l构。注意第一个SELECT命o(h)的parent列设|成了NULLQ这表示QStoreQ元素处于最层的位|?
以黑色表C的数据成点的属性或元素Q例如,Store_ID通过列名提供了这斚w的信息。列名字中的?”是分隔W,d可分成四(四个参数Q,其中W四个参数是可选的。这些参数描q的是:(x)
W一个参数描q该列所属元素的名字Q在q里是<StoreQ元素?
W二个是标签~号Q它指定了该列信息在XML?wi)Şl构中所处位|?
W三个参数指定XML文档内的属性或元素名字。在q里名字指定为id?
数据列默认被创徏为参?所指定节点的属性,即id成为<StoreQ节点的属性。如果要指定id是<StoreQ的一个子元素Q我们可以用第四个可选的参数Q这个参数的一个作用就是让我们把该Ҏ(gu)定ؓ(f)元素Q例如store!1!id!element?
׃使用了UNION ALL操作W来q结SELECT语句Qؓ(f)了保证SQL查询的合法性,所有SELECT语句的选择l果必须h相同数量的列。我们用NULL关键词来补SELECT语句Q从而避免了重复数据?
通过EXPLICIT模式查询所生成的XML文和通过AUTO模式生成的完全相同,那么Z么要创徏EXPLICIT模式查询呢?
假设现在有h要求在XML文中包含商店的打折信息。查看Pubs数据库,我们得知每个商店都可以有0到n范围内的折扣率。因此,一U合理的Ҏ(gu)是在QStoreQ元素下面加上子元素QDiscountQ,q样我们得到如下XML文l构Q?
QSTORESQ?BR>QSTORE Id=&single;&single; Name=&single;&single;Q?BR>QDISCOUNT Type=&single;&single; LowQty=&single;&single; HighQty=&single;&single;Q?BR>QAMOUNTQ</AMOUNTQ?BR>Q?DISCOUNTQ?BR>QSALE OrdNo=&single;&single; Qty=&single;&single;Q?BR>Q?SALEQ?BR>Q?STOREQ?BR>Q?STORESQ? |
q里的改动包括:(x)
要在QSaleQ元素所在的层次增加一个XML元素QDiscountQ,卻IDiscountQ是QStroeQ的子元素?
Amount嵌套在<DiscountQ里面,但不应该是<DiscountQ元素的属性?
在AUTO模式中是不可能实现这些改动的?
下面是创个新XML文的EXPLICIT模式查询Q?
【图 2A?/P>
SELECT 1 as Tag, NULL as Parent, s.stor_id as [Store!1!id], s.stor_name as [Store!1!name], NULL as [Sale!2!orderno], NULL as [Sale!2!1ty], NULL as [Discount!3!type], NULL as [Discount!3!lowqty], NULL as [Discount!3!highqty], NULL as [Discount!3!amount!element] FROM stores s UNION ALL SELECT 2, 1, s.stor_id, s.stor_name, sa.ord_num, sa.qty, NULL, NULL, NULL, NULL FROM stores s, sales sa WHERE s.stor_id = sa.stor_id UNION ALL SELECT 3, 1, NULL, s.stor_name, NULL, NULL, d.discounttype, d.lowqty, d.highqty, d.discount FROM stores s, discounts d WHERE s.stor_id = d.stor_id ORDER BY [store!1!name] For XML EXPLICIT |
Z创徏?A所昄的EXPLICIT模式查询Q我们对?的查询进行了如下修改Q?
增加了第三个子查询提取折扣数据,通过Tag列声明这些数据的标签gؓ(f)3?
通过指定Parent列ؓ(f)1折扣数据设|成QStoreQ元素的子元素?
注意在第三个SELECT子查询中我们只包含了那些必需的列Qƈ用NULL补I列。这个子查询包含store_name列,虽然Discount元素q不要用到这个列Q但如果把这个列也设|ؓ(f)NULLQ则l果Universal表将不会(x)按照解析器所要求的那样以节点升序排序Q不妨自p一下看看)。Universal表的排序列也可以用Tag列替代?
为维持结果Universal表的完整性,W一、二两个SELECT语句也用NULL补以反映ؓ(f)折扣数据增加的列?
为指定新折扣列的元数据修改了W一个SELECT语句?
通过在第四个参数中声明element指定Amount列ؓ(f)Discount的一个元素(element是可在第四个参数中声明的多个指o(h)之一Q?
下面q个XML文只能用EXPLICIT模式生成Q?
l果XML文档中不?x)显C出NULL数据Q如折扣lowqty和highqty?/P>
看来上面的介l,大家可能已经对FOR XML的语法有所了解。通过FOR XML 我们在能够在Query Analyzer 中直接返回一个XML格式的数据或者通过其他多样化表现方式将XML格式的数据显C出来,比如可以数据显C在览器上。下面这个例子就使用FOR XML和ADO数据输出到览器的例子?/P>
Dim adoConn Dim sConn Dim adoCmd Dim sQuery ‘徏立ADODB Stream 对象QADODB Stream 对象需要ADO2.5以上版本支持Q它可以记录集转换为数据流?BR>Dim adoStreamQuery Response.write "Pushing XML to client for processing " & "QBR/Q? adoCmd.Properties("Output Stream") = Response ‘通过IE的XML解析器,使用DOMҎ(gu)XML的文本{换ؓ(f)HTML Dim xmlDoc Dim root, child For each child in root.childNodes Q?SCRIPTQ? |
W3C ?1999 q?10 ?8 日提出的 XPath 语言规范Q它是一U基于XML的查询语aQ它能在XML文挡中处理数据。SQL Server 2000 中实现的是该规范的子集。它把table和views作ؓ(f)XML的组Ӟq把columns作ؓ(f)XML属性。SQL Server 2000的XML支持IIS使用URL或者模板的方式提交到SQL Server处理Xpath查询Qƈq回XML的结果?
支持的功?
下表昄 SQL Server 2000 中实现的 XPath 语言的功能?/P>
功能 | 目 |
---|---|
?/TD> | attribute?B>child?B>parent ?self ?/TD> |
包括q箋谓词和嵌套谓词在内的布尔D?/TD> | |
所有关p运符 | =, !=, Q? Q?, Q? Q? |
术q算W?/TD> | +, -, *, div |
昑ּ转换函数 | number()?B>string()?B>Boolean() |
布尔q算W?/TD> | AND, OR |
布尔函数 | true()?B>false()?B>not() |
XPath 变量 |
下表昄 SQL Server 2000 中没有实现的 XPath 语言的功能?/P>
功能 | 目 |
---|---|
?/TD> | ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling |
数D?/TD> | |
术q算W?/TD> | mod |
节点函数 | ancestor、ancestor-or-self、descendant、descendant-or-self (//)、following、following-sibling、namespace、preceding、preceding-sibling |
字符串函?/TD> | string()、concat()、starts-with()、contains()、substring-before()、substring-after()、substring()、string-length()、normalize()、translate() |
布尔函数 | lang() |
数字函数 | sum()、floor()、ceiling()、round() |
Union q算W?/TD> | | |
XPath 查询是以表达式的形式指定的。位|\径是一U比较常用表辑ּQ用以选择相对于上下文节点的节炚w。位|\径表辑ּ的求值结果是节点集?
XML 文档 QrootQ?BR> Qorder productid="Prod-28" unitprice="45.6" quantity="15"Q?BR> QdiscountQ?.25Q?discountQ?BR> Q?orderQ? Qorder productid="Prod-39" unitprice="18" quantity="21"Q?BR> QdiscountQ?.25Q?discountQ? Q?orderQ?BR> Qorder productid="Prod-46" unitprice="12" quantity="2"Q? QdiscountQ?.25Q?discountQ?BR> Q?orderQ? Q?rootQ? |
下面是查询该XML 文的XPath位置路径表达式,它的含义是返回根节点下所有<ROOTQ子元素下的ProductID属性的属性gؓ(f) "prod-39"?QorderQ?元素?/P>
位置路径的类?/B>
可以分ؓ(f)l对位置路径和相对位|\径?
l对位置路径以文的根节点开始,由斜?(/) l成Q后面可以是相对位置路径。斜?(/) 选定文档的根节点?
相对位置路径以文的上下文节点(ContextQ开始,由斜?(/) 所分开的一个或多个位置步骤序列l成。每个步骤都选定相对于上下文节点的节炚w。初始步骤序列选定相对于上下文节点的节炚w。节炚w中的每个节点都用作后l步骤的上下文节炏V由后箋步骤标识的节炚w联接在一赗例如,child::Order/child::OrderDetail 选定上下文节点的QorderQ?子元素的 QorderdetailQ?子元素?
位置步骤 Q绝Ҏ(gu)相对Q位|\径由包含下面三部分的位置步骤l成Q?
?
轴指定位|步骤选定的节点与上下文节点之间的?wi)关pRSQL Server 2000 支持 parent、child、attribute ?self 轴?
如果在位|\径中指定 child _(d)查询选定的所有节炚w是上下文节点的子节炏V?BR>比如说要查询从当前的上下文节点中选定所?QOrderQ节点的子节?可以使用 child:: Order
如果指定 parent _(d)选定的节点将是上下文节点的父节点?
比如说要查询从当前的上下文节点中选定所?QOrderQ节点的父节?可以使用 parent:: Order
如果指定 attribute _(d)选定的节Ҏ(gu)上下文节点的属性?BR>比如说要查询从当前的上下文节点中选定所?QOrderQ节点的属?可以使用 attribute:: Order
节点试
节点试指定位置步骤选定的节点类型。每个uQchild、parent、attribute ?selfQ都h主要节点cd。对?attribute _(d)主要节点cd?QattributeQ。对?parent、child ?self _(d)主要节点cd?QelementQ?/P>
例如Q如果位|\径指?child::OrderQ则选定上下文节点的 QOrderQ?子元素。因?child 轴以 QelementQ?为其主要节点cdQ而且如果Order?QelementQ?节点Q则节点试Order?TRUE?/P>
选择谓词Q零个或多个Q?/B>
谓词围绕着轴筛选节炚w。在 XPath 表达式中指定选择谓词与在 SELECT 语句中指?WHERE 子句怼。谓词在括号中指定。应用在选择谓词中指定的试对节点试q回的节点进行筛选。对于要{选的节点集中的每个节点,在对谓词表达式取值时此节点作ؓ(f)上下文节点,节炚w中的节点CZ下文大小。如果谓词表辑ּҎ(gu)节点取gؓ(f) TRUEQ则此节点将包括在最后所得到的节炚w中?/P>
例如Q?
1. Child::Order [attribute::ProductID="Prod-39"] 表示从当前的上下文节点中选定ProductID属性gؓ(f)Prod-39的所?QorderQ子节点?/P>
2. Child::Order [child:: Discount] 表示从当前的上下文节点中选定包含一个或多个 QDiscountQ?子节点的所?QOrderQ?子节炏V?/P>
3. Child::Order [not(child:: Discount)] 表示从当前的上下文节点中选定不包?QDiscountQ?子节点的所?QOrderQ?子节炏V?/P>
位置步骤的语?/B>
是用两个冒号 (::) 分开的u名和节点试Q后面是分别攑֜Ҏ(gu)号中的零个或多个表达式?/P>
例如Q在 XPath 表达式(位置路径Qchild::Order[attribute::ProductID="prod-39"]中,选定上下文节点的所?QorderQ?子元素。然后将谓词中的试应用于节炚wQ将只返?ProductID属性的属性gؓ(f) "prod-39"?QorderQ?元素节点?
~略语法
Sqlservr2000支持下面的位|\径羃略语?
attribute::可以~略?@?
比如Q[attribute::ProductID="Prod-39"] 可以~写?[@ProductID =" Prod-39"]
child::可以在位|步骤中省略?BR> 比如Q位|\径child::ROOT/child::Orde可以~写?ROOT /Order
self::node() 可羃略ؓ(f)一个句?(.)Q?parent::node() 可羃略两个句?(..)?/P>
所?/child::ROOT/child::Order[attribute::ProductID="prod-39"]也可以羃写成 /ROOT/Order[@ProductID="prod-39"]
表结构是q样Q?BR>node_id int //节点id
parentNode_id int //父节点id
node_text varchar //节点内容
isModule bit //是否叶子节点
现在保存的数据有Q?/P>
node_id parentNode_id node_text isModule
1 -1 语言与文?nbsp; 0
2 -1 数学 0
3 -1 技?nbsp; 0
4 1 语文 0
5 1 外语 0
6 5 p 0
7 6 初中p 0
8 7 Ҏ(gu)?nbsp; 1
9 4 定? 1
10 2 试3 1
现在问题是:(x)
能否通过做一个存储过E,
Ҏ(gu)表中的isModule字段的取|取gؓ(f)1的表C最l叶子结点)Q?BR>比如“特斯塔”ؓ(f)叶子节点Q层层向上递进扑ֈ”特斯塔“的先节点Q?BR>Ҏ(gu)?〉初中英?〉英?〉外?〉语a与文?BR>即通过”特斯塔“找到”语a与文学“来
最l返回的形态ؓ(f)Q?BR>叶子节点id 父节点id 节点名称 先节点名称 先节点id
8 7 Ҏ(gu)?nbsp; 语言与文?nbsp; 1
9 4 定? 语言与文?nbsp; 1
10 2 试3 数学 2
/////////////////////////////////////////////////////////////////////////
正确{案Q?/P>
--生成试数据
create table xkb_treeNode(
node_id int,
parentNode_id int,
node_textvarchar(10),
isModulebit)
insert into xkb_treeNode select 1 ,-1,'语言与文?,0
insert into xkb_treeNode select 2 ,-1,'数学',0
insert into xkb_treeNode select 3 ,-1,'技?,0
insert into xkb_treeNode select 4 , 1,'语文',0
insert into xkb_treeNode select 5 , 1,'外语',0
insert into xkb_treeNode select 6 , 5,'p',0
insert into xkb_treeNode select 7 , 6,'初中p',0
insert into xkb_treeNode select 8 , 7,'Ҏ(gu)? ,1
insert into xkb_treeNode select 9 , 4,'定?',1
insert into xkb_treeNode select 10 , 2,'试3',1
--创徏存储q程
create procedure sp_test
as
begin
select
a.node_id,
a.parentNode_id,
a.node_text,
b.node_id as ancestor_id ,
b.node_text as ancestor_text
into
#t
from
xkb_treeNode a,xkb_treeNode b
where
a.parentNode_id = b.node_id and a.isModule = 1
while(exists(select 1 from xkb_treeNode a,#t b where a.node_id=ancestor_id and a.parentNode_id != -1))
begin
update #t
set
ancestor_id = b.p_id,
ancestor_text = b.p_text
from
#t a,
(select
c.node_id,
d.node_id as p_id,
d.node_text as p_text
from
xkb_treeNode c,xkb_treeNode d
where
c.parentNode_id = d.node_id) b
where
a.ancestor_id = b.node_id
end
select * from #t order by node_id
end
--执行存储q程Q结果楼主自q
exec sp_test
可以ZM使用 SQL 语句的目的来使用存储q程Q它h以下优点Q?
存储q程的功能取决于数据库所提供的功能?/P>
可?Transact-SQL 语句 CREATE PROCEDURE 创徏存储q程。创建存储过E前Q请考虑下列事项Q?
创徏存储q程Ӟ应指定:(x)
Microsoft] SQL Server?2000 中的许多理zd是通过一U称?!--GLOSSARY-->
强烈(zhn)不要创Z sp_ 为前~的存储过E。SQL Server 始终按照下列序查找?sp_ 开头的存储q程Q?
因此Q虽然当前数据库中可能存在带 sp_ 前缀的用户创建的存储q程Q但M(x)先检?master 数据库(即该存储过E已用数据库名称限定Q?/P>
重要 如果用户创徏的存储过E与pȝ存储q程同名Q则永远不执行用户创建的存储q程?/P>
如果一个不同的标识可予某q程Q则可以用与现有某存储过E相同的名称创徏该过E,q样可允许将q些q程q行逻辑分组。同名的分组q程可以同时删除。在同一应用E序中用的q程一般都以该方式分组。例如,用于 my_app 应用E序的过E可能被命名?my_proc;1?B>my_proc;2 {。删?my_proc 卛_除该整个l。将q程分组后,无法删除该l内的单个过E?/P>
专用和全局临时存储q程与(f)时表cMQ都可以用向该过E名U添?# ?## 前缀的方法进行创建? 表示本地临时存储q程Q?# 表示全局临时存储q程。SQL Server 关闭后,q些q程不再存在?/P>
临时存储q程在连接到 SQL Server 的早期版本时很有用,q些早期版本不支持再ơ?Transact-SQL 语句或批处理执行计划。连接到 SQL Server 2000 的应用程序应使用 sp_executesql pȝ存储q程Q而不使用临时存储q程。有x多信息,请参?FONT color=#800080>执行计划的高速缓存和重新使用?
只有创徏本地临时q程的连接才能执行该q程Q当该连接关闭(用户?SQL Server 中注销Q时Q将自动删除该过E?/P>
Mq接都可执行全局临时存储q程。只有创q程的用h用的q接关闭Qƈ且所有其它连接所用的该过E的当前执行版本q行完毕后,全局临时存储q程才不再存在。一旦用于创q程的连接关闭,不再允许启动执行该全局临时存储q程。只允许那些已启动执行该存储q程的连接完成该q程的运行?/P>
如果直接?tempdb 数据库中创徏没有 # ?## 前缀的存储过E,则由于每ơ启?SQL Server ?tempdb 都要重新创徏Q因此当关闭 SQL Server 时将自动删除该存储过E。直接在 tempdb 中创建的q程即在创q程的连接终止后也会(x)存在。与M其它对象一P可向其他用户授予、拒l和废除执行该(f)时存储过E的权限?/P>
创徏存储q程Q存储过E是保存h的可以接受和q回用户提供的参数的 Transact-SQL 语句的集合?/P>
可以创徏一个过E供怹使用Q或在一个会(x)话中临时使用Q局部(f)时过E)Q或在所有会(x)话中临时使用Q全局临时q程Q?/P>
也可以创建在 Microsoft] SQL Server?启动时自动运行的存储q程?/P>
CREATE PROC [ EDURE ] procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
procedure_name
新存储过E的名称。过E名必须W合标识W规则,且对于数据库及其所有者必d一。有x多信息,请参?FONT color=#800080>使用标识W?/FONT>?/P>
要创建局部(f)时过E,可以?procedure_name 前面加一个编L(fng) (#procedure_name)Q要创徏全局临时q程Q可以在 procedure_name 前面加两个编L(fng) (##procedure_name)。完整的名称Q包?# ?##Q不能超q?128 个字W。指定过E所有者的名称是可选的?/P>
;number
是可选的整数Q用来对同名的过E分l,以便用一?DROP PROCEDURE 语句卛_同l的q程一起除厅R例如,名ؓ(f) orders 的应用程序用的q程可以命名?orderproc;1?B>orderproc;2 {。DROP PROCEDURE orderproc 语句除L个组。如果名UC包含定界标识W,则数字不应包含在标识W中Q只应在 procedure_name 前后使用适当的定界符?/P>
@parameter
q程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。用户必d执行q程时提供每个所声明参数的|除非定义了该参数的默认|。存储过E最多可以有 2.100 个参数?/P>
使用 @ W号作ؓ(f)W一个字W来指定参数名称。参数名U必ȝ合标识符的规则。每个过E的参数仅用于该q程本nQ相同的参数名称可以用在其它q程中。默认情况下Q参数只能代替常量,而不能用于代替表名、列名或其它数据库对象的名称。有x多信息,请参?EXECUTE?
data_type
参数的数据类型。所有数据类型(包括 text?B>ntext ?imageQ均可以用作存储q程的参数。不q,cursor 数据cd只能用于 OUTPUT 参数。如果指定的数据cd?cursorQ也必须同时指定 VARYING ?OUTPUT 关键字。有?SQL Server 提供的数据类型及其语法的更多信息Q请参见数据cd?
说明 对于可以?cursor 数据cd的输出参敎ͼ没有最大数目的限制?/P>
VARYING
指定作ؓ(f)输出参数支持的结果集Q由存储q程动态构造,内容可以变化Q。仅适用于游标参数?/P>
default
参数的默认倹{如果定义了默认|不必指定该参数的值即可执行过E。默认值必L帔R?NULL。如果过E将对该参数使用 LIKE 关键字,那么默认g可以包含通配W(%、_、[] ?[^]Q?/P>
OUTPUT
表明参数是返回参数。该选项的值可以返回给 EXEC[UTE]。?OUTPUT 参数可将信息q回l调用过E?B>Text?B>ntext ?image 参数可用?OUTPUT 参数。?OUTPUT 关键字的输出参数可以是游标占位符?/P>
n
表示最多可以指?2.100 个参数的占位W?/P>
{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
RECOMPILE 表明 SQL Server 不会(x)~存该过E的计划Q该q程在q行旉新编译。在使用非典型值或临时D不希望覆盖~存在内存中的执行计划时Q请使用 RECOMPILE 选项?/P>
ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 CREATE PROCEDURE 语句文本的条目。?ENCRYPTION 可防止将q程作ؓ(f) SQL Server 复制的一部分发布?/P>
说明 在升U过E中QSQL Server 利用存储?syscomments 中的加密注释来重新创建加密过E?/P>
FOR REPLICATION
指定不能在订阅服务器上执行ؓ(f)复制创徏的存储过E?使用 FOR REPLICATION 选项创徏的存储过E可用作存储q程{选,且只能在复制q程中执行。本选项不能?WITH RECOMPILE 选项一起用?/P>
AS
指定q程要执行的操作?/P>
sql_statement
q程中要包含的Q意数目和cd?Transact-SQL 语句。但有一些限制?/P>
n
是表C此q程可以包含多条 Transact-SQL 语句的占位符?/P>
存储q程的最大大ؓ(f) 128 MB?/P>
用户定义的存储过E只能在当前数据库中创徏Q(f)时过E除外,临时q程L?tempdb 中创建)。在单个批处理中QCREATE PROCEDURE 语句不能与其?Transact-SQL 语句l合使用?
默认情况下,参数可ؓ(f)I。如果传?NULL 参数值ƈ且该参数?CREATE ?ALTER TABLE 语句中用,而该语句中引用的列又不允怋?NULLQ则 SQL Server ?x)生一条错误信息。ؓ(f)了防止向不允怋?NULL 的列传?NULL 参数|应向q程中添加编E逻辑或ؓ(f)该列使用默认|使用 CREATE ?ALTER TABLE ?DEFAULT 关键??/P>
在存储过E的M CREATE TABLE ?ALTER TABLE 语句中都为每列显式指?NULL ?NOT NULLQ例如在创徏临时表时。ANSI_DFLT_ON ?ANSI_DFLT_OFF 选项控制 SQL Server 为列指派 NULL ?NOT NULL Ҏ(gu)的方式Q如果在 CREATE TABLE ?ALTER TABLE 语句中没有指定的话)。如果某个连接执行的存储q程对这些选项的设|与创徏该过E的q接的设|不同,则ؓ(f)W二个连接创建的表列可能?x)有不同的?f)I性,q且表现Z同的行ؓ(f)方式。如果ؓ(f)每个列显式声明了 NULL ?NOT NULLQ那么将Ҏ(gu)有执行该存储q程的连接用相同的为空性创Z(f)时表?/P>
在创建或更改存储q程ӞSQL Server 保?SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 的设|。执行存储过E时Q将使用q些原始讄。因此,所有客L(fng)?x)话?SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 讄在执行存储过E时都将被忽略。在存储q程中出现的 SET QUOTED_IDENTIFIER ?SET ANSI_NULLS 语句不媄响存储过E的功能?/P>
其它 SET 选项Q例?SET ARITHABORT、SET ANSI_WARNINGS ?SET ANSI_PADDINGSQ在创徏或更改存储过E时不保存。如果存储过E的逻辑取决于特定的讄Q应在过E开头添加一?SET 语句Q以保讄正确。从存储q程中执?SET 语句Ӟ该设|只在存储过E完成之前有效。之后,讄恢复ؓ(f)调用存储q程时的倹{这使个别的客户端可以设|所需的选项Q而不?x)媄响存储过E的逻辑?/P>
说明 SQL Server 是将I字W串解释为单个空D是解释ؓ(f)真正的空字符Ԍ由兼容别设|控制。如果兼容别小于或{于 65QSQL Server 将I字W串解释为单个空根{如果兼容别等?70Q则 SQL Server 空字符串解释ؓ(f)I字W串。有x多信息,请参?B> sp_dbcmptlevel?
若要昄用来创徏q程的文本,请在q程所在的数据库中执行 sp_helptextQƈ使用q程名作为参数?
说明 使用 ENCRYPTION 选项创徏的存储过E不能?sp_helptext 查看?/P>
若要昄有关q程引用的对象的报表Q请使用 sp_depends?
若要E重命名Q请使用 sp_rename?
SQL Server 允许创徏的存储过E引用尚不存在的对象。在创徏Ӟ只进行语法检查。执行时Q如果高速缓存中无有效的计划,则编译存储过E以生成执行计划。只有在~译q程中才解析存储q程中引用的所有对象。因此,如果语法正确的存储过E引用了不存在的对象Q则仍可以成功创建,但在q行时将p|Q因为所引用的对象不存在。有x多信息,请参?FONT color=#800080>延迟名称解析和编?/FONT>?
SQL Server 允许 Transact-SQL 存储q程在创建时引用不存在的表。这U能力称为gq名U解析。不q,如果 Transact-SQL 存储q程引用了该存储q程中定义的表,而兼容别设|(通过执行 sp_dbcmptlevel 来设|)?65Q则在创建时?x)发告信息。而如果在q行时所引用的表不存在,返回错误信息。有x多信息,请参?sp_dbcmptlevel ?FONT color=#800080>延迟名称解析和编?/FONT>?
成功执行 CREATE PROCEDURE 语句后,q程名称存储在 sysobjects pȝ表中Q?CREATE PROCEDURE 语句的文本将存储?syscomments 中。第一ơ执行时Q将~译该过E以定索数据的最佌问计划?/P>
存储q程只能?cursor 数据cd用于 OUTPUT 参数。如果ؓ(f)某个参数指定?cursor 数据cdQ也必须指定 VARYING ?OUTPUT 参数。如果ؓ(f)某个参数指定?VARYING 关键字,则数据类型必L cursorQƈ且必L?OUTPUT 关键字?/P>
说明 cursor 数据cd不能通过数据?APIQ例?OLE DB、ODBC、ADO ?DB-LibraryQ绑定到应用E序变量上。因为必dl定 OUTPUT 参数Q应用程序才可以执行存储q程Q所以带?cursor OUTPUT 参数的存储过E不能通过数据?API 调用。只有将 cursor OUTPUT 变量赋值给 Transact-SQL 局?cursor 变量Ӟ才可以通过 Transact-SQL 批处理、存储过E或触发器调用这些过E?/P>
在执行过E时Q以下规则适用?cursor 输出参数Q?
说明 I结果集与空g同?/P>
说明 关闭状态只有在q回时才有媄响。例如,可以在过E中关闭游标Q稍后再打开游标Q然后将该游标的l果集返回给调用批处理、存储过E或触发器?/P>
SQL Server 支持两种临时q程Q局部(f)时过E和全局临时q程。局部(f)时过E只能由创徏该过E的q接使用。全局临时q程则可由所有连接用。局部(f)时过E在当前?x)话l束时自动除厅R全局临时q程在用该q程的最后一个会(x)话结束时除去。通常是在创徏该过E的?x)话l束时?/P>
临时q程?# ?## 命名Q可以由M用户创徏。创E后Q局部过E的所有者是唯一可以使用该过E的用户。执行局部(f)时过E的权限不能授予其他用户。如果创Z全局临时q程Q则所有用户均可以讉K该过E,权限不能昑ּ废除。只有在 tempdb 数据库中h昑ּ CREATE PROCEDURE 权限的用P才可以在该数据库中显式创Z(f)时过E(不用编L(fng)命名Q。可以授予或废除q些q程中的权限?
说明 频繁使用临时存储q程?x)?tempdb 中的pȝ表上产生争用Q从而对性能产生负面影响。徏议?sp_executesql 代替?B>sp_executesql 不在pȝ表中存储数据Q因此可以避免这一问题?/P>
SQL Server 启动时可以自动执行一个或多个存储q程。这些存储过E必ȝpȝ理员创建,q在 sysadmin 固定服务器角色下作ؓ(f)后台q程执行。这些过E不能有M输入参数?
对启动过E的数目没有限制Q但是要注意Q每个启动过E在执行旉?x)占用一个连接。如果必d启动时执行多个过E,但不需要ƈ行执行,则可以指定一个过E作为启动过E,让该q程调用其它q程。这样就只占用一个连接?/P>
在启动时恢复了最后一个数据库后,卛_始执行存储过E。若要蟩q这些存储过E的执行Q请启动参数指定ؓ(f)跟踪标记 4022。如果以最低配|启?SQL ServerQ?-f 标记Q,则启动存储过E也不会(x)执行。有x多信息,请参?FONT color=#0000ff>跟踪标记?
若要创徏启动存储q程Q必M?sysadmin 固定服务器角色的成员dQƈ?master 数据库中创徏存储q程?/P>
使用 sp_procoption 可以Q?
存储q程可以嵌套Q即一个存储过E可以调用另一个存储过E。在被调用过E开始执行时Q嵌套增加,在被调用q程执行l束后,嵌套U将减少。如果超出最大的嵌套U,?x)整个调用q程铑֤败。可?@@NESTLEVEL 函数q回当前的嵌套?/P>
若要估计~译后的存储q程大小Q请使用下列性能监视计数器?
性能监视器对象名 | 性能监视计数器名U?/TH> |
---|---|
SQLServerQ缓冲区理?/TD> | 高速缓存大(面敎ͼ |
SQLServerQ高速缓存管理器 | 高速缓存命中率 |
高速缓存页 | |
高速缓存对象计? |
* 各种分类的高速缓存对象均可以使用q些计数器,包括Ҏ(gu) sql、准?sql、过E、触发器{?/P>
有关更多信息Q请参见 SQL Server:Buffer Manager 对象?SQL Server:Cache Manager 对象?
除了 SET SHOWPLAN_TEXT ?SET SHOWPLAN_ALL 之外Q这两个语句必须是批处理中仅有的语句Q,M SET 语句均可以在存储q程内部指定。所选择?SET 选项在存储过E执行过E中有效Q之后恢复ؓ(f)原来的设|?
如果其他用户要用某个存储过E,那么在该存储q程内部Q一些语句用的对象名必M用对象所有者的名称限定。这些语句包括:(x)
CREATE PROCEDURE 的权限默认授?sysadmin 固定服务器角色成员和 db_owner ?db_ddladmin 固定数据库角色成员?B>sysadmin 固定服务器角色成员和 db_owner 固定数据库角色成员可以将 CREATE PROCEDURE 权限转让l其他用戗执行存储过E的权限授予q程的所有者,该所有者可以ؓ(f)其它数据库用戯|执行权限?/P>
下面的存储过E从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版C。该存储q程不用Q何参数?/P>
USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info_all' AND type = 'P') DROP PROCEDURE au_info_all GO CREATE PROCEDURE au_info_all AS SELECT au_lname, au_fname, title, pub_name FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_id GO
au_info_all 存储q程可以通过以下Ҏ(gu)执行Q?/P>
EXECUTE au_info_all -- Or EXEC au_info_all
如果该过E是批处理中的第一条语句,则可使用Q?/P>
au_info_all
下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程接受与传递的参数_匚w的倹{?/P>
USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info' AND type = 'P') DROP PROCEDURE au_info GO USE pubs GO CREATE PROCEDURE au_info @lastname varchar(40), @firstname varchar(20) AS SELECT au_lname, au_fname, title, pub_name FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_id WHERE au_fname = @firstname AND au_lname = @lastname GO
au_info 存储q程可以通过以下Ҏ(gu)执行Q?/P>
EXECUTE au_info 'Dull', 'Ann' -- Or EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann' -- Or EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull' -- Or EXEC au_info 'Dull', 'Ann' -- Or EXEC au_info @lastname = 'Dull', @firstname = 'Ann' -- Or EXEC au_info @firstname = 'Ann', @lastname = 'Dull'
如果该过E是批处理中的第一条语句,则可使用Q?/P>
au_info 'Dull', 'Ann' -- Or au_info @lastname = 'Dull', @firstname = 'Ann' -- Or au_info @firstname = 'Ann', @lastname = 'Dull'
下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程对传递的参数q行模式匚wQ如果没有提供参敎ͼ则用预讄默认倹{?/P>
USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'au_info2' AND type = 'P') DROP PROCEDURE au_info2 GO USE pubs GO CREATE PROCEDURE au_info2 @lastname varchar(30) = 'D%', @firstname varchar(18) = '%' AS SELECT au_lname, au_fname, title, pub_name FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON t.pub_id = p.pub_id WHERE au_fname LIKE @firstname AND au_lname LIKE @lastname GO
au_info2 存储q程可以用多U组合执行。下面只列出了部分组合:(x)
EXECUTE au_info2 -- Or EXECUTE au_info2 'Wh%' -- Or EXECUTE au_info2 @firstname = 'A%' -- Or EXECUTE au_info2 '[CK]ars[OE]n' -- Or EXECUTE au_info2 'Hunter', 'Sheryl' -- Or EXECUTE au_info2 'H%', 'S%'
OUTPUT 参数允许外部q程、批处理或多?Transact-SQL 语句讉K在过E执行期间设|的某个倹{下面的CZ创徏一个存储过E?(titles_sum)Qƈ使用一个可选的输入参数和一个输出参数?/P>
首先Q创E:(x)
USE pubs GO IF EXISTS(SELECT name FROM sysobjects WHERE name = 'titles_sum' AND type = 'P') DROP PROCEDURE titles_sum GO USE pubs GO CREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUT AS SELECT 'Title Name' = title FROM titles WHERE title LIKE @@TITLE SELECT @@SUM = SUM(price) FROM titles WHERE title LIKE @@TITLE GO
接下来,该 OUTPUT 参数用于控制语a?
说明 OUTPUT 变量必须在创和用该变量旉q行定义?/P>
参数名和变量名不一定要匚wQ不q数据类型和参数位置必须匚wQ除非?@@SUM = variable 形式Q?
DECLARE @@TOTALCOST money EXECUTE titles_sum 'The%', @@TOTALCOST OUTPUT IF @@TOTALCOST < 200 BEGIN PRINT ' ' PRINT 'All of these titles can be purchased for less than $200.' END ELSE SELECT 'The total cost of these titles is $' + RTRIM(CAST(@@TOTALCOST AS varchar(20)))
下面是结果集Q?/P>
Title Name ------------------------------------------------------------------------ The Busy Executive's Database Guide The Gourmet Microwave The Psychology of Computer Cooking (3 row(s) affected) Warning, null value eliminated from aggregate. All of these titles can be purchased for less than $200.
OUTPUT 游标参数用来存储过E的局部游标传递回调用批处理、存储过E或触发器?/P>
首先Q创Z下过E,?titles 表上声明q打开一个游标:(x)
USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'titles_cursor' and type = 'P') DROP PROCEDURE titles_cursor GO CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT AS SET @titles_cursor = CURSOR FORWARD_ONLY STATIC FOR SELECT * FROM titles OPEN @titles_cursor GO
接下来,执行一个批处理Q声明一个局部游标变量,执行上述q程以将游标赋值给局部变量,然后从该游标提取行?/P>
USE pubs GO DECLARE @MyCursor CURSOR EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT WHILE (@@FETCH_STATUS = 0) BEGIN FETCH NEXT FROM @MyCursor END CLOSE @MyCursor DEALLOCATE @MyCursor GO
如果E提供的参数不是典型的参敎ͼq且新的执行计划不应高速缓存或存储在内存中QW(xu)ITH RECOMPILE 子句?x)很有帮助?/P>
USE pubs IF EXISTS (SELECT name FROM sysobjects WHERE name = 'titles_by_author' AND type = 'P') DROP PROCEDURE titles_by_author GO CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%' WITH RECOMPILE AS SELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name', title AS Title FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id INNER JOIN titles t ON ta.title_id = t.title_id WHERE au_lname LIKE @@LNAME_PATTERN GO
WITH ENCRYPTION 子句对用户隐藏存储过E的文本。下例创建加密过E,使用 sp_helptext pȝ存储q程获取关于加密q程的信息,然后试直接?B> syscomments 表中获取关于该过E的信息?/P>
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'encrypt_this' AND type = 'P') DROP PROCEDURE encrypt_this GO USE pubs GO CREATE PROCEDURE encrypt_this WITH ENCRYPTION AS SELECT * FROM authors GO EXEC sp_helptext encrypt_this
下面是结果集Q?/P>
The object's comments have been encrypted.
接下来,选择加密存储q程内容的标识号和文本?/P>
SELECT c.id, c.text FROM syscomments c INNER JOIN sysobjects o ON c.id = o.id WHERE o.name = 'encrypt_this'
下面是结果集Q?/P>
说明 text 列的输出昄在单独一行中。执行时Q该信息与 id 列信息出现在同一行中?/P>
id text ---------- ------------------------------------------------------------ 1413580074 ?????????????????????????????????e????????????????????????????????????????? (1 row(s) affected)
下面的示例创Z个过E,昄表名?emp 开头的所有表及其对应的烦引。如果没有指定参敎ͼ该过E将q回表名?sys 开头的所有表Q及索引Q?/P>
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'sp_showindexes' AND type = 'P') DROP PROCEDURE sp_showindexes GO USE master GO CREATE PROCEDURE sp_showindexes @@TABLE varchar(30) = 'sys%' AS SELECT o.name AS TABLE_NAME, i.name AS INDEX_NAME, indid AS INDEX_ID FROM sysindexes i INNER JOIN sysobjects o ON o.id = i.id WHERE o.name LIKE @@TABLE GO USE pubs EXEC sp_showindexes 'emp%' GO
下面是结果集Q?/P>
TABLE_NAME INDEX_NAME INDEX_ID ---------------- ---------------- ---------------- employee employee_ind 1 employee PK_emp_id 2 (2 row(s) affected)
下面的示例显C四个过E以及gq名U解析的各种可能使用方式。尽引用的表或列在~译时不存在Q但每个存储q程都可创徏?/P>
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'proc1' AND type = 'P') DROP PROCEDURE proc1 GO -- Creating a procedure on a nonexistent table. USE pubs GO CREATE PROCEDURE proc1 AS SELECT * FROM does_not_exist GO -- Here is the statement to actually see the text of the procedure. SELECT o.id, c.text FROM sysobjects o INNER JOIN syscomments c ON o.id = c.id WHERE o.type = 'P' AND o.name = 'proc1' GO USE master GO IF EXISTS (SELECT name FROM sysobjects WHERE name = 'proc2' AND type = 'P') DROP PROCEDURE proc2 GO -- Creating a procedure that attempts to retrieve information from a -- nonexistent column in an existing table. USE pubs GO CREATE PROCEDURE proc2 AS DECLARE @middle_init char(1) SET @middle_init = NULL SELECT au_id, middle_initial = @middle_init FROM authors GO -- Here is the statement to actually see the text of the procedure. SELECT o.id, c.text FROM sysobjects o INNER JOIN syscomments c ON o.id = c.id WHERE o.type = 'P' and o.name = 'proc2' 转自: http://goaler.xicp.net/ShowLog.asp?ID=515
说明Q复制表(只复制结?源表名:(x)a 新表名:(x)b)
说明Q拷贝表(拯数据,源表名:(x)a 目标表名Qb)
说明Q显C文章、提交h和最后回复时?/FONT>
说明Q外q接查询(表名1Qa 表名2Qb)
说明Q日E安排提前五分钟提醒
说明Q两张关联表Q删除主表中已经在副表中没有的信?BR>SQL:
说明Q?-
SQL:
说明Q?-
SQL:
说明Q?BR>从数据库中去一q的各单位电(sh)话费l计(?sh)话费定额贺电(sh)化肥清单两个表来源Q?BR>SQL:
说明Q四表联查问题:(x)
说明Q得到表中最的未用的ID?BR>SQL:
·Binary [(n)]
·Varbinary [(n)]
·Char [(n)]
·Varchar[(n)]
·Nchar[(n)]
·Nvarchar[(n)]
·Datetime
·Smalldatetime
·Decimal[(p[,s])]
·Numeric[(p[,s])]
·Float[(n)]
·Real
·Int
·Smallint
·Tinyint
·Money
·Smallmoney
·Bit
·Cursor
·Sysname
·Timestamp
·Uniqueidentifier
·Text
·Image
·Ntext
(1)二进制数据类?
二进制数据包?Binary、Varbinary ?Image.
Binary 数据cd既可以是固定长度?Binary),也可以是变长度的?
Binary[(n)] ?n 位固定的二进制数据。其中,n 的取D围是?1 ?8000。其存储H的大小?n + 4 个字节?
Varbinary[(n)] ?n 位变长度的二q制数据。其中,n 的取D围是?1 ?8000。其存储H的大小?n + 4个字节,不是 n 个字节?
?Image 数据cd中存储的数据是以位字W串存储的,不是?SQL Server 解释的,必须由应用程序来解释。例如,应用E序可以使用 BMP、TIEF、GIF ?JPEG 格式把数据存储在 Image 数据cd中?
(2)字符数据cd
字符数据的类型包?CharQVarchar ?Text?
字符数据是由M字母、符号和数字Ll合而成的数据?
Varchar 是变长字W数据,光度不过 8KB。Char 是定长字W数据,光度最多ؓ(f) 8KB。超q?8KB 的ASCII 数据可以使用Text 数据cd存储。例如,因ؓ(f) Html 文全部都是 ASCII 字符Qƈ且在一般情况下长度过 8KBQ所以这些文可?Text 数据cd存储?SQL Server 中?
(3)Unicode 数据cd
Unicode 数据cd包括 Nchar,Nvarchar 和Ntext?
?Microsoft SQL Server 中,传统的非 Unicode 数据cd允许使用q定字W集定义的字W。在 SQL Server 安装q程中,允许选择一U字W集。?Unicode 数据cdQ列中可以存储Q何由Unicode 标准定义的字W。在 Unicode 标准中,包括了以各种字符集定义的全部字符。用Unicode 数据cdQ所战胜的窨是用非 Unicode 数据cd所占用的窨大小的两倍?
?SQL Server 中,Unicode 数据?Nchar、Nvarchar ?Ntext 数据cd存储。用这U字W类型存储的列可以存储多个字W集中的字符。当列的长度变化Ӟ应该使用 Nvarchar 字符cdQ这时最多可以存?4000 个字W。当列的长度固定不变Ӟ应该使用 Nchar 字符cdQ同Pq时最多可以存?4000 个字W。当使用 Ntext 数据cdӞ该列可以存储多于 4000 个字W?
(4)日期和时间数据类?
日期和时间数据类型包?Datetime ?Smalldatetime 两种cd?
日期和时间数据类型由有效的日期和旉l成。例如,有效的日期和旉数据包括?/01/98 12:15:00:00:00 PM”和?:28:29:15:01 AM 8/17/98”。前一个数据类型是日期在前Q时间在后一个数据类型是霎时间在前,日期在后。在 Microsoft SQL Server 中,日期和时间数据类型包括Datetime ?Smalldatetime 两种cdӞ所存储的日期范围是?1753 q?1 ?1 日开始,?9999 q?2 ?31 日结?每一个D?8 个存储字?。?Smalldatetime 数据cdӞ所存储的日期范围是 1900 q?1 ?1?开始,?2079 q?12 ?31 日结?每一个D?4 个存储字??
日期的格式可以设定。设|日期格式的命o(h)如下Q?
Set DateFormat {format | @format _var|
其中Qformat | @format_var 是日期的序。有效的参数包括 MDY、DMY、YMD、YDM、MYD ?DYM。在默认情况下,日期格式?MDY?
例如Q当执行 Set DateFormat YMD 之后Q日期的格式为年 ??形式Q当执行 Set DateFormat DMY 之后Q日期的格式??月有q?形式
Q?Q数字数据类?
数字数据只包含数字。数字数据类型包括正数和负数、小敎ͼ点敎ͼ和整??
整数由正整数和负整数l成Q例?39?5?-2 ?33967。在 Micrsoft SQL Server 中,整数存储的数据类型是 IntQSmallint ?Tinyint。Int 数据cd存储数据的范围大?Smallint 数据cd存储数据的范_(d)?Smallint 据类型存储数据的范围大于 Tinyint 数据cd存储数据的范围。?Int 数据狗昔存储数据的范围是?-2 147 483 648 ?2 147 483 647Q每一个D?4个字节存储空_(d)。?Smallint 数据cdӞ存储数据的范围从 -32 768 ?32 767Q每一个D?个字节存储空_(d)。?Tinyint 数据cdӞ存储数据的范围是? ?55Q每一个D?个字节存储空_(d)?
_娄数据?SQL Server 中的数据cd?Decimal ?Numeric。这U数据所占的存储I间Ҏ(gu)该数据的位数后的位数来确定?
在SQL Server 中,q似数数据的数据类型是 Float ?Real。例如,三分之一q个分数C?333333Q当使用q似数据cd时能准确表示。因此,从系l中索到的数据可能与存储在该列中数据不完全一栗?
Q?Q货币数据表C正的或者负的货币数?。在 Microsoft SQL Server 中,货币数据的数据类型是Money ?Smallmoney。Money 数据cd要求 8 个存储字节,Smallmoney 数据cd要求 4 个存储字节?
Q?Q特D数据类?
Ҏ(gu)数据cd包括前面没有提过的数据类型。特D的数据cd?U,?Timestamp、Bit ?Uniqueidentifier?
Timestamp 用于表示SQL Server zd的先后顺序,以二q投q格式表示。Timestamp 数据与插入数据或者日期和旉没有关系?
Bit ?1 或?0 l成。当表示真或者假、ON 或?OFF Ӟ使用 Bit 数据cd。例如,询问是否是每一ơ访问的客户求可以存储在q种数据cd的列中?
Uniqueidentifier ?16 字节的十六进制数字组成,表示一个全局唯一的。当表的记录行要求唯一ӞGUID是非常有用。例如,在客h识号列用这U数据类型可以区别不同的客户?
2.用户定义的数据类?
用户定义的数据类型基于在 Microsoft SQL Server 中提供的数据cd。当几个表中必须存储同一U数据类型时Qƈ且ؓ(f)保证q些列有相同的数据类型、长度和可空性时Q可以用用户定义的数据cd。例如,可定义一U称?postal_code 的数据类型,它基?Char 数据cd?
当创建用户定义的数据cdӞ必须提供三个敎ͼ(x)数据cd的名U、所Z的系l数据类型和数据cd的可I性?
Q?Q创建用户定义的数据cd
创徏用户定义的数据类型可以?Transact-SQL 语句。系l存储过E?sp_addtype 可以来创建用户定义的数据cd。其语法形式如下Q?
sp_addtype {type},[,system_data_bype][,'null_type']
其中Qtype 是用户定义的数据cd的名U。system_data_type 是系l提供的数据cdQ例?Decimal、Int、Char {等?null_type 表示该数据类型是如何处理I值的Q必M用单引号引v来,例如'NULL'?NOT NULL'或?NONULL'?
例子Q?
Use cust
Exec sp_addtype ssn,'Varchar(11)',"Not Null'
创徏一个用户定义的数据cd ssnQ其Z的系l数据类型是变长?1 的字W,不允许空?
例子Q?
Use cust
Exec sp_addtype birthday,datetime,'Null'
创徏一个用户定义的数据cd birthdayQ其Z的系l数据类型是 DateTimeQ允许空?
例子Q?
Use master
Exec sp_addtype telephone,'varchar(24),'Not Null'
Eexc sp_addtype fax,'varchar(24)','Null'
创徏两个数据cdQ即 telephone ?fax
Q?Q删除用户定义的数据cd
当用户定义的数据cd不需要时Q可删除。删除用户定义的数据cd的命令是 sp_droptype {'type'}?
例子Q?
Use master
Exec sp_droptype 'ssn'
注意Q当表中的列q正在用用户定义的数据cdӞ或者在其上面还l定有默认或者规则时Q这U用户定义的数据cd不能删除?
2.数据库的相关操作
1.如何创徏数据?
(1).使用 Create Database 创徏数据?
Create Database 语名的语法Ş式如下:(x)
Create Database database_name
[On
{[Primary](Name=logical_file_name,
Filename='os_file_name'
[,Size=size]
[,Maxsize=max_size]
}[,...n]
]
[Log On
}(Name=Logical_name,
Filename='os_file_name'
[,Size=size])
}[,...n]
]
[For Restore]
注释Q?
PrimaryQ该选项是一个关键字Q用来指定主文gl中的文件。主文gl不公包含了数据库系l表中的全部内容Q而且q包含了没有在用h件组中包含的全部对象。一个数据库只能有一个主文g。在默认情况下,卛_没有指定Primary关键字时Q列在语句中的第一个文件就是主文g?
NameQ该选项指定数据库的逻辑名字Q这是在SQL Server pȝ中用的名称Q是数据库在SQL Server 中标识符?
FilenameQ该选项用来指定数据库所在文件的操作pȝ文g名称和\径。在os_file_name中的路径必须是SQL Server 所在服务器上的一个文件夹。该操作pȝ文g名称与Name 的逻辑名称是一一对应的?
SizeQ该选项用来指定数据库操作系l文件的大小。在指定文g大小的时候,既可以用MB单位Q也可以使用KB单位。如果没有指定单位,那么pȝ默认的单位是MB。文件最是1MBQ也是_(d)数据库所在的文g不能于1MB。在默认情况下,数据库数据文件的大小?MBQ数据库日志文g的大是 1MB?
MaxsizeQ该选项用来指定操作pȝ文g可以增长的最大尺寸。在指定文g增长寸的时候,既可以用MB单位Q也可以使用KB单位。如果没有指定单位,那么pȝ的默认单位是MB。如果没有指定文件可以增长的最大尺寸,那么pȝ的增长是没有限制的,可以占满整个盘I间?
FielGrowthQ该选取用来指定文件的增量Q当然该选项不能与Maxsize选项有冲H。该选项指定的数据gؓ(f)零时Q表C文件不能增ѝ该选项可以用MB、KB和百分比指定?
例子Q?
创徏一个cust数据库,该数据库的主数据文g的逻辑名称是cust_dataQ操作系l文件是cust.mdfQ大是15MBQ最大是 30MBQ以20%的速度增加Q该数据库的日志文g的逻辑名称是cust_logQ操作系l是cust.ldfQ大是3MBQ最大是10MBQ以1MB 的速度增加?
Create Database cust
On
Primary (Name=cust_data,
Filename='d:cust.mdf',
Size=15MB,
Maxsize=30MB,
Filegrowth=20%)
Log On
(Name=cust_log,
Filename='d:cust.ldf',
Size=3MB,
Maxsize=10MB,
FileGrowth=1MB)
2.如何增加数据库的大小
(1).使用Alter Database命o(h)来增加数据库文g的大?
如果在创建数据库文g时没有配|文件的大小自动增长Q那么可以用Alter Database命o(h)来增加文件的大小?
例子Q?
数据库cust的数据文件cust_data的大调整ؓ(f)50MB?
Alter Database cust
Modify File (Name='cust_data',Size=50)
(2).使用Add File 增加一个次要文?
通过为数据库增加ơ要的数据文件和日志文g来增加数据库的大?
例子Q?
Alter Database cust
Add File
(Name=cust_data2,Filename='d:cust2.mdf',
Size=5MB,
Maxsize=10MB,
Filegrowth=10%)
3.压羃数据库和数据文g
(1)使用Dbcc Shrinkdatabase 命o(h)压羃整个数据?
例子Q?
cust数据库的大小压羃?0%
Dbcc Shrinkdatabase (cust,10)
(2)使用Dbcc ShrinkFile命o(h)压羃数据库中的某一个数据文?
例子Q?
cust数据文g的大压~到5MB
Dbcc ShrinkFile (cust,5)
4.删除数据?
(1)使用Drop命o(h)删除数据?
例子Q?
删除cust数据?
Drop Database cust
3.表的相关操作Q?
1.创徏?
(1)用Create Table 命o(h)创徏?
语法Q?
Create Table tabl_name
({
}column_name As computed_column_expression
}
}[,...n]
)
[On {fiegroup | Default}]
[Textimage_On {fiegroup | Default}]
例子Q?
打开cust数据库,创徏一个表Q该表包含了学生的有关信息,x学号、姓名、性别、出生日期、籍贯、联pȝ(sh)话、住址和备注信息?
Use cust
Create Table students
(
number int not null,
name varchar(10) not null,
sex char(2) null,
birthday datetime null,
hometown varchar(30) null,
telphone_no varchar(12) null,
address varchar(30) null,
others varchar(50) null
)
在这个表中number表示学生代号Q数据类型ؓ(f)intQ不允许为空Qname表示学生姓名Q数据类型ؓ(f)varcharQ长度ؓ(f)10Q不允许为空Q?sex表示学生的性别Q数据类型ؓ(f)charQ长度ؓ(f)2Q允ؓ(f)I;birthday表示学生的出生日期,数据cd为datetimeQ允ؓ(f)I; hometown表示学生的籍贯,数据cd为varcharQ长度ؓ(f)30Q允ؓ(f)I;telephone_no表示学生的联pȝ(sh)脑,数据cd?varcharQ长度ؓ(f)12Q允ؓ(f)I;address表示学生的住址Q数据类型ؓ(f)varcharQ长度ؓ(f)30Q允ؓ(f)I;others表示学生的备注信息,长度?0Q允ؓ(f)I?
2.修改表的l构
(1)使用T-SQL语句增加和删除一个新?
语法Q?
Alter Table table
{
ADO
{[]
|colun_name As computed_column_expression
|[]
}[,...n]
|Drop
{Column column
}[,...n]
}
例子Q打开cust数据库,修改其中的表students的结构,增加一个新字段Q字D名为yingQ数据类型是varcharQ长度是10Q没有默认|充许为空?
Use cust
Alter Table students Add ying varchar(10) null
打开cust数据库,修改其中的表students的结构,删除一个字D,字段名ؓ(f)ying?
Use cust
Alter Table students Drop Column ying
3.向表中插入数?
(1)?Insert 语句
语法如下Q?
Insert [Into]
{table_name|view_name}[(column_list)]
{Values|values_list|select_statement}
注意Q在插入数据Ӟ字符数据和日期数据要使用引号引v来?
例子Q?
Use cust
Insert Into students
Values (11,"影子","?,"1999-12-12","湖北","83779805","武汉市桥口区","VB爱好?)
打开cust数据库,向students表中插入数据
(2)用Default 选项
在插入数据时Q可以用Default选项。Default选项有两UŞ式,一UŞ式是Default ValuesQ另一U是Default?
Default Values 形式中的某一行的所有列插入默认倹{用这UŞ式的前提条g是表中的所有列必须是这四种cd之一QIdentity属性,Timestamp数据cdQ允ؓ(f)NullQ或者有一个指定的默认倹{否则,?x)错误信息?
例子Q?
Use cust
Insert Into students Default Values
q个例子?x)出现错误,因?f)students表的number字段是设|ؓ(f)不允ؓ(f)I的?
Default 形式是ؓ(f)表中的某一列插入默认倹{要插入的该列必d备一定的条gQ即该列要么是Timestamp 数据cdQ要么是允许为NullQ要么是有一个指定的默认|否则Q会(x)出现错误信息?
例子Q?
Use cust
Insert Into students Values(11,"影子",Default,Default,Default,Default,Default,Default)
由天?个字D不能ؓ(f)I,所以要赋|否则?x)出现错误,而后面的6个字D允ؓ(f)I,因此可以调用Default默认?
(3)插入部分数据
在用Insert语句插入数据是,q可以插入部分数据,也就是可以ؓ(f)每一行的指定的部分列插入数据。在插入部分数据Ӟ应该注意以下三个问题Q?
☆在 Insert 子句中,指定要插入数据的列名?
☆在 Values 子句中,列出与列名对应的数据。列名的序和数据的序应该完全对应?
☆在 Insert 子句中,没有列出的列应该臛_hq四U类型之一QIdenttty 属性,Timestamp 数据cdQ允ؓ(f) NullQ或者有一个指定的默认倹{否则,?x)出现错误信息?
例子Q?
Use cust
Insert Into students (number,name)
Values (110,"影子")
打开cust数据库,向students表中插入一行数?
注意Q如用下例语句将发生错误Q因为name字段是不允许为空的(在创建数据库时设定的Q?
Insert Into students (number)
Values (110)
(4)?Select 语句插入多条数据
Insert 语句插入数据的特Ҏ(gu)每一ơ只能插入一行数据。相反,Select 也可以用?Insert 语句中,q且可以一ơ插入多条数据。?Select 语句插入数据的语法Ş式如下:(x)
Insert table_name
Select column_list
From table_list
Where search_conditions
在?Select 语句插入数据Ӟ应该注意下面几点Q?
☆在 Insert 语句中?Select Ӟ他们参考的表既可以是相同的Q也可以是不同的?
☆要插入数据的表必须已经存在?
☆要插入数据的表必须?Select 的结果集兼容。兼容的含义是列的数量和序必须相同Q列的数据类型或者相同,或者SQL Server 可以自动转换?
例子Q?
Use cust
Insert students
Select number,name,sex,birthday,hometown,telphone_no,address,others
From students
注意Q?
Select 后面的字D要输完_(d)q个例子是自己向自己插入多条数据Q自己向自己插入是被允许的)
补充Q?
你还可以“From students”后面加上“Where name="影子"”,只插入name{于影子的记录,可以用And ?Or 加上多个条g?
(5)使用 Select Into 插入数据C个新表中
带有 Into 子句?Select 语句允许用户定义一个新表ƈ且把数据插入到新表中。这U方法不同于前面讲述的那些方法。在前面的那些方法中Q一个共同的特点Q是在数据输入之前表已经存在。而?Select Into 插入数据的方法,是在插入数据的过E中建立新表?
Select Into 语句的语法如下:(x)
Select select_list
Into new_table_name
From table_list
Where search_conditions
在?Select Into 插入数据Ӟ要注意下面几点:(x)
☆在某个数据库中使用 Select Into 插入数据Ӟ讄该数据库?Select Into/Bulk Copy 为真?
☆新表不能存在,否则?x)生错误信息?
☆新表中的列和行是基于查询结果集
☆要插入的数据不记录在日志中?
☆在select_list 中出现的列应该用别名,否则Q新表中的列没有列名。没列名的表只能通过 Select * From new_table_name 的Ş式查询。因此,应该为列起个别名?
☆这U方法多用在对列q行各种计算的情c?
例子Q?
Select number,name
Into newcust1
From students
创徏新的表newcust1Q插入students表中的number和name字段的所有数据?
补充Q如果要插入所有字D늚记录Q则“Select *”,也可在“From students”后加条ӞҎ(gu)和上个例子一栗?
(6)?UPdate 语句修改表中的数?
Update 语句用来修改表中已存在的数据。Update 语句既可以一ơ修改一行数据,也可以一ơ修改许多行Q甚臛_以一ơ修改表中的全部数据。Update 语句使用 Where 子句指定要修改的行,使用 Set 子句l出新的数据。新数据可以是常量,也可以是指定的表辑ּQ还可以是?From 子句来自其他表的数据?
Update 语句的语法如下:(x)
Update {table_name|view_name}
Set {column_list}=expression [Q? . .]
[Where clause]
在?Update 语句Ӟ如果没有使用 Where 子句Q那么就对表中所有的行进行修攏V如果用Update 语句修改数据时与数据完整性约束有冲突Q那么修改就不会(x)发生Q整个修改事务全部滚回。例如,q种冲突可能是所输入的值是错误的数据类型,或者所输入的D背了在该列定义的规则U束Q等{?
例子Q?
Use cust
Update students
Set name=name+"007"
Where number>100
打开cust数据库,修改students表,使number>100的数据的name的值全部加"007"?
4.?Delete 语句删除表中的数?
当数据库中的数据不需要的q修可以删除。一般情况下Q删除数据?Delete 语句。Delete 语句可以一ơ从一个表中删除一条或者多条数据行?
Delete 语句的语法如下:(x)
Delete [From] table_name
Where search_conditions
?Delete 语句中如果用了 Where 子句Q那么就从指定的表中删除满 Where 子句条g的数据行?
例子Q?
Use cust
Delete students
Where number>100
删除 students中,number>100的数?
补充Q?
如果?Delete 语句中没有指?Where 子句Q那么就表中所有的记录全部删除Q即 Delete students 语句删除表中的全部记录?
在删除表中的全部数据Ӟq可以?Truncate Table 语句。Truncate Table 语句?Delete 语句都可以将表中的全部数据删除,但是Q两条语句又有不同的特点。当用户使用 Delete 语句删除数据Ӟ被删除的数据要记录在日志中。ƈ不将Ҏ(gu)据的变化记录在日志中。因此,使用 Truncate Table students 语句删除记录的速度快于使用 Delete students 语句删除表中记录的速度?
5.?Drop Table 命o(h)删除?
当数据库中的表不需要时可以删除。删除表可以使用 Drop Table 语句。删除表是删除表的定义以及表的全部数据、烦引、触发器、约束和指定该表的许可。当删除表时Q基于表的视图不能被删除Q必M?Drop View 语句删除视图?
Drop Table 语句的语法如下:(x)
Drop Table table_name
例子Q?
Use cust
Drop Table students
删除cust数据库中的students表?
补充Q?
不能使用 Drop Table 语句删除正在被约束参考的表,必须首先要么删除外键U束Q要么删除参考表。表的所有者可以删除表。当删除表是Ӟl定在该表上的规则或者默认则失掉了绑定,该表的约束或者触发器则自动被删除。如果重新创Q必重新绑定相应的规则和默认、重新创发器和增加必要的U束。另外,pȝ表不能删除?
删除表的许可属于表的所有者。然而,数据所有者(DBOQ、系l管理员QSAQ和DLL理员可以删除数据库中的M对象?
4.数据的检?/P>
1.?Select 子句索记?
Select 子句是每一个检索数据的查询核心。它告诉数据库引擎返回什么字Dc?
Select 子句的常见Ş式是Q?
Select *
该子句的意思是“返回在所指定的记录源中能扑ֈ的所有字D”。这U命令Ş式很方便Q因Z无需知道从表中检索的字段名称。然而,索表中的所有列是低效的。因此,因该只检索需要的字段Q这样可以大大的提高查询的效率?
2.使用 From 子句指定记录?
From 子句说明的是查询索记录的记录源;该记录源可以是一个表或另一个存储查询?
你还能从多个表中索记录,q在后面的章节中介l?
例子Q?
Select * From students 索students表中的所有记?
3.?Where 子句说明条g
Where 子句告诉数据库引擎根据所提供的一个或多个条g限定其检索的记录。条件是一个表辑ּQ可h真假两种判断?
例子Q?
Select * From students Where name="影子"
q回students中name字段为媄子的列表Q这ơ所q回的结果没有特定顺序,除非你用了 Order By 子句。该子句在后面的章节介l?
注意QWhere 子句中的文本字符串界限符是双引号Q在VB中因改ؓ(f)单引P因ؓ(f)在VB中字W串的界定符是双引号?
补充Q?
使用 And ?Or 逻辑可以两个或更多的条仉接到一起以创徏更高U的 Where 子句?
例子Q?
Select * From students Where name="影子" And number>100
q回name为媄子number大于100的列表?
例子Q?
Select * From students Where name="影子" And (number>100 Or number<50)
q回name为媄子,number大于100或者小?0的列表?
Where 子句中用到的操作W?
操作W?功能
< 于
<= 于或等?
> 大于
>= 大于或等?
= {于
<> 不等?
Between 在某个取D围内
Like 匚w某个模式
In 包含在某个值列表中
SQL中的{于和不{于{操作符与VB中的意义和用相?
例子Q?
Q?Q?Between 操作W?
Use cust
Select * From students
Where number Between 1 and 100
Between 操作W返回的是位于所说明的界限之内的所有记录倹{这个例子就q回 number 字段 1 ?100 之间的全部记录?
Q?Q? Like 操作W和通配W?
Use cust
Select * From students
Where name Like "%?"
Like 操作W把记录匚wC说明的某个模式。这个例子是q回含“媄”的L字符丌Ӏ?
四种通配W的含义
通配W?描述
% 代表零个或者多个Q意字W?
_Q下划线Q?代表一个Q意字W?
[] 指定范围内的L单个字符
[^] 不在指定范围内的L单个字符
全部CZ子如下:(x)
Like "BR%" q回?BR"开始的L字符?
Like "br%" q回?Br"开始的L字符?
Like "%een" q回?een"l束的Q意字W串
Like "%en%" q回包含"en"的Q意字W串
Like "_en" q回?en"l束的三个字W串
Like "[CK]%" q回?C"或?K"开始的L字符?
Like "[S-V]ing" q回长ؓ(f)四个字符的字W串Q结是"ing"Q开始是从S到V?
Like "M[^c]%" q回?M"开始且W二个字W不?c"的Q意字W串?
4. 使用 Order By 对结果排?
Order By 子句告诉数据库引擎对其检索的记录q行排序。可以对M字段排序Q或者对多个字段排序Qƈ且可以以升序或隆序进行排序?
在一个正式的 Select 查询之后包含一?Order By 子句Q后跟想排序的字D(可以有多个)便可以说明一个排序顺序?
例子Q?
Use cust
Select * From students
Where name Like "%?"
Order By number
对返回的l果?number q行排序?
以降序排?
如要以隆序排序,只需在排序的字段之后使用 Desc 关键字?
例子Q?
Use cust
Select * From students
Where name Like "%?"
Order By number Desc
5. 使用 Top 昄某个范围的第一个记录或最后一个记录?
使用 Top 关键字可以只昄一个大记录前面或后面的数几个记录。在查询中,Top 关键字与排序子句一hl果集限制ؓ(f)数几个记录或按某个癑ֈ比显C整个结果记录集合中的一部分?
例子Q?
Select Top 3 * From students q回 students 表中的前3条记?
Select Top 10 Percent * From students q回 students 表中前面?0%个记?
Select Top 3 * From students Order By number desc q回 students 表中 number 最大的Q最后)?条记?
6. ?As 对字D名q行别名?
Z么在查询中对字段命以别名Q或重新命名Q这样做的原因有两个Q?
☆所涉及的表的字D名很长Q想使字D在l果集中更易处理一些?
☆创建的查询产生了某些计或合计列,需要对之进行命名?
不管是什么原因对字段命以别名Q在 SQL 中都可以Ҏ(gu)C?As 子句做得?
例子Q?
Select number As 学号 ,name As 姓名 From students
7. 合ƈ查询
合ƈ查询Q?Union Query Q用于合q具有相同字D늻构的两个表的内容Q如果想在一个结果集中显C多个记录源中的不相关的记录Ӟq十分有用?
例子Q?
Select *
From students
Union
Select *
From students1
该查询结果集?students ?students1 中的记录合ƈC个结果中Q其输出和原表归之前一模一栗?
注意Q缺省情况下Q合q查询不?x)返回重复记录(如果记录归pȝ在把记录拷到归表中后不相应的记录删除Q这时该功能有用了Q,可以加上 All 关键字而让合ƈ查询昄重复记录?
例子Q?
Select *
From students
Union All
Select *
From students1
该合q查询显C?students 表和 students1 表的内容Ӟ没有寚w复记录进行处?
补充Q?
Union q算W允许把两个或者多个查询结果合q到一个查询结果集中。如果比?Union ?Join 两咱q算W,那么 Union q算W增加行的数量,?Join q算W增加列的数量。?Union 时应该注意,两个l果中的列的l构必须匚wQ数据类型必d容等{?
Union q算W的语法形式如下Q?
Select select_list
From clause
Where clause
Group By clause
Having clause
Union [All]
Select select_list
From clause
Where clause
Group By clause
Having clause
Order By clause
Compute clause
对于 Union q算W,有下列几炚w要说明:(x)
·在默认情况下QUnion q算W删除全部冗余行。如果用All 选项Q那么冗余行不删除?
·?Union 语句中的全部 select_list 必须有相同数量的列、兼容的数据cdq且按照同样的顺序出现?
·在结果集中,列名来自W一?Select 语句?
8.q接查询
在实际用过E中l常需要同时从两个表或者两个以上表中检索数据。连接就是允许同时从两个表或者两个以上表中检索数据,指定q些表中某个或者某些列作ؓ(f)q接条g。在 SQL Server 中,可以使用两种q接语法形式Q一U是 Ansi q接语法形式Q这是连接用?From 子句中,另外一U是 SQL Server q接语句形式Q这是连接用?Where 子句中?
Ansi q接语法形式如下Q?
Select table_name.column_name,table_name.column_name,...
From {table_name [join_type] Join table_name On search_conditions}
Where [search_conditions]
?Ansi 语法形式中,可以 Ansi q接关键字来定使用的连接Ş式。例如:(x)
☆?Inner Join 关键字,l果集中仅包含满x件的行?
☆?Cross Join 关键字,l果集中包含两个表中所有行的组合?
☆?Outer Join 关键字,l果集中既包含那些满x件的行,q包含那些其中某个表的全部行?
SQL Server q接语法形式如下所C:(x)
Select table_name.column_name,table_name.column_name,...
From [table_name,tab
/*
功能Q?BR> Ҏ(gu)@CXZT的状态,对于字段@FdNameq行内容@FdRecord的匹配?BR> 当@FdRecord中有内容的时候,q行匚w
当@GSBM中有内容的时候,dGSBM的条?BR> 输入:
@FdName 字段名称
@FdRecord 字段内容
@GSBM
@CXZT 查询状?0-表示_Q?-表示模糊Q?-表示
该状态仅对KHMC起作?BR> 输出Q?BR> @Cond 条g语句 例如:
输入 dwmc,'上v',1,'RRL'
输出 dwmc like '上v%' and gsbm='RRL'
*/
/*
创徏人:(x)
创徏日期Q?BR> --对于改存储过E的版本更新记录在这个地?/P>
*/
declare @HaveFdRecord as int
Set @HaveFdRecord = 0
Set @Cond = ''
/* dFdRecord */
if len(rtrim(ltrim(@FdRecord)))>0
begin
select @Cond=
case @CXZT
when 0 then
@Cond + @FdName + N'=''' + @FdRecord + ''''
when 1 then
@Cond + @FdName + N' like ''' + @FdRecord + '%'''
when 2 then
@Cond + @FdName + N' like ''%' + @FdRecord + '%'''
end
set @HaveFdRecord = 1
end
/* dGSBM */
if len(rtrim(ltrim(@GSBM)))>0
begin
if @HaveFdRecord=1
begin
Set @Cond = @Cond + ' and '
end
set @Cond = @Cond + ' gsbm=''' + @GSBM + ''''
end
GO
==============================================================
CREATE Procedure sp_Math_KHYE
@KHMC nvarchar(250),
@JZRQ datetime,
@CXZT int,
@GSBM nvarchar(10)
as
/*
功能Q?BR> 输入Q?BR> @KHMC 客户名称
@CXZT 查询状?0-表示_Q?-表示模糊Q?-表示
该状态仅对KHMC起作?BR> @JZRQ 截至日期
@GSBM
输出Q?BR> @ReturnKHYE Ҏ(gu)条g计算出来的客户余?BR> 说明Q在调用该过E前Q需按照如下语句定义一个命名ؓ(f)#KHYEReturn的(f)时表
Create Table #KHYEReturn
(dwmc nvarchar(250),khye decimal(15,6))
在用完?KHYEReturn后,应该立刻使用下列语句释放该(f)时表
delete from #KHYEReturn
drop Table #KHYEReturn
*/
/*
实现Ҏ(gu)Q?BR>
*/
/*
创徏人:(x)
创徏日期Q?/P>
--对于改存储过E的版本更新记录在这个地?/P>
*/
Declare @SqlString nvarchar(1000)
Declare @Cond nvarchar(250)
-- 制作查询条gQ存入@Cond
EXECUTE sp_MakeCond 'dwmc',@KHMC,@CXZT,@GSBM,@Cond output
/* */
set @SqlString = 'select dwmc,sum(xhsl*hsj) as xsje from xsdda where xsrq<=@vJZRQ and ' + @Cond
set @SqlString = @SqlString + ' group by dwmc'
Create table #sp_Math_KHYE_XSJE(dwmc nvarchar(250),xsje decimal(15,6))
Declare @ParmDefinition nvarchar(100)
set @ParmDefinition = '@vKHMC nvarchar(250),@vJZRQ datetime'
-- q个地方是调用sp_executesql来执行动态SqlStringq将l果q回C张(f)时表里面
-- 在这里,曄试图结果返回到游标中间Q但是没有成功?BR>-- Ҏ(gu)资料 insert ?exec 是不能够嵌套执行的,不过在这个地Ҏ(gu)较奇怪,q两个可以嵌套执行?BR>-- 需要注意的地方Q@ParmDefnition是用来定义在sp_executesql中间要用的变量的?BR>-- 曄试验q个地方直接传一个字W串Q不使用变量传递,l果报错。不知道有没有其它的人成功过
-- 在@ParmDefinition后面p传递一个变量列表,按照我的理解Q?BR>-- 是在这个地方给sp_executesqlq程中要使用的变量(也就是Sql语句的变量)赋?BR>
insert into #sp_Math_KHYE_XSJE EXECUTE sp_executesql @SqlString,
@ParmDefinition,
@vKHMC=@KHMC,
@vJZRQ=@JZRQ
/* */
set @SqlString = ''
set @SqlString = 'select dwmc,sum(bcsk+ysk) as fkje from xhskdda where skrq<=@vJZRQ and ' + @Cond
set @SqlString = @SqlString + ' group by dwmc'
Create table #sp_Math_KHYE_FKJE(dwmc nvarchar(250),fkje decimal(15,6))
set @ParmDefinition=''
set @ParmDefinition = '@vKHMC nvarchar(250),@vJZRQ datetime'
insert into #sp_Math_KHYE_FKJE EXECUTE sp_executesql @SqlString,
@ParmDefinition,
@vKHMC=@KHMC,
@vJZRQ=@JZRQ
Create Table #sp_Math_KHYE_Result(
dwmc nvarchar(250),khye decimal(15,6))
-- 比较单的Sql语句了,左联双QBT的需求,只能用BT的写?/P>
insert into #sp_Math_KHYE_Result
select distinct T1.dwmc as dwmc,(T1.fkje-T1.xsje) as khye from
(
select
#sp_Math_KHYE_XSJE.dwmc as dwmc,
isnull(#sp_Math_KHYE_XSJE.xsje,0) as xsje,
isnull(#sp_Math_KHYE_FKJE.fkje,0) as fkje
from #sp_Math_KHYE_XSJE,#sp_Math_KHYE_FKJE
where #sp_Math_KHYE_XSJE.dwmc*=#sp_Math_KHYE_FKJE.dwmc
union
select
#sp_Math_KHYE_XSJE.dwmc as dwmc,
isnull(#sp_Math_KHYE_XSJE.xsje,0) as xsje,
isnull(#sp_Math_KHYE_FKJE.fkje,0) as fkje
from #sp_Math_KHYE_XSJE,#sp_Math_KHYE_FKJE
where #sp_Math_KHYE_FKJE.dwmc*=#sp_Math_KHYE_XSJE.dwmc
) as T1
insert into #KHYEReturn select * from #sp_Math_KHYE_Result
GO
==================================================================
CREATE Procedure sp_KHYEXYTJ
@StartDate datetime,
@EndDate datetime,
@KHMC nvarchar(250),
@CXZT int,
@GSBM nvarchar(100)
as
/*
功能Q?BR> 输入:
@StartDate 开始日?BR> @EndDate 截至日期
@KHMC 客户名称
@CXZT 查询状?0-表示_Q?-表示模糊Q?-表示
该状态仅对KHMC起作?BR> @GSBM
输出Q?BR>
表结构:(x)
dwmc ncye ssye bqxs qmye khxye cxye
*/
/*
创徏人:(x)
创徏日期Q?/P>
--对于改存储过E的版本更新记录在这个地?/P>
*/
-- q个地方求了一堆ؕ七八p的数据Q是需要用来输出的?/P>
-- 求得?sp_KHYEXYTJ_QMKHYE
Create Table #sp_KHYEXYTJ_QMKHYE
(dwmc nvarchar(250),QMkhye decimal(15,6))
Create Table #KHYEReturn
(dwmc nvarchar(250),khye decimal(15,6))
execute sp_Math_KHYE @KHMC,@EndDate,@CXZT,@GSBM
insert into #sp_KHYEXYTJ_QMKHYE(dwmc,QMKHYE) select * from #KHYEReturn
delete from #KHYEReturn
-- 求得?sp_KHYEXYTJ_QMKHYE
Declare @NowDate datetime
set @NowDate = GetDate()
Create Table #sp_KHYEXYTJ_KHYE
(dwmc nvarchar(250),khye decimal(15,6))
execute sp_Math_KHYE @KHMC,@NowDate,@CXZT,@GSBM
insert into #sp_KHYEXYTJ_KHYE select * from #KHYEReturn
delete from #KHYEReturn
-- 求得?sp_KHYEXYTJ_NCYE
Create Table #sp_KHYEXYTJ_NCYE
(dwmc nvarchar(250),ncye decimal(15,6))
Set @NowDate=cast(str(year(GetDate()))+'-01-01 00:00:00' as datetime)
execute sp_Math_KHYE @KHMC,@NowDate,@CXZT,@GSBM
insert into #sp_KHYEXYTJ_NCYE select * from #KHYEReturn
delete from #KHYEReturn
drop table #KHYEReturn
--
Declare @SqlString nvarchar(500)
Declare @Cond nvarchar(100)
-- q里也是求查询条件的地方
EXECUTE sp_MakeCond 'dwmc',@KHMC,@CXZT,@GSBM,@Cond output
set @SqlString = 'select dwmc,sum(xhsl*hsj) as xsje from xsdda where xsrq<=@vEndDate and xsrq>=@vStartDate and ' + @Cond
set @SqlString = @SqlString + ' group by dwmc'
Create table #sp_KHYEXYTJ_XSJE(dwmc nvarchar(250),xsje decimal(15,6))
Declare @ParmDefinition nvarchar(100)
set @ParmDefinition = '@vKHMC nvarchar(250),@vEndDate datetime,@vStartDate datetime'
insert into #sp_KHYEXYTJ_XSJE EXECUTE sp_executesql @SqlString,
@ParmDefinition,
@vKHMC=@KHMC,
@vEndDate=@EndDate,
@vStartDate=@StartDate
-- 制作输出?BR> Create Table #sp_KHYEXYTJ_ReslutTable
(dwmc nvarchar(250),
ncye decimal(15,6),
ssye decimal(15,6),
bqxs decimal(15,6),
qmye decimal(15,6),
khxye decimal(15,6),
cxye decimal(15,6))
-- 下面是一堆ؕ七八p的东西了。本来是数据放到游标中去,然后Ҏ(gu)标进行@环处?BR> -- 不过好像速度却很慢,一共是3张数据表Q三章表数据分别?k,4k,2WQ?BR> -- 用游标处理,最l返回统计表600条数据用?7U,一个比较让人发?c)旉?BR> -- 可能是我写的不好吧,但是q个旉也确实太长了
-- 所以,又换成按照临时表来处理Q分别将各个需要统计的数据分开l计Q?BR> -- 然后攑օC同的临时表里面,最后再所有的数据Ҏ(gu)dwmcq个字段q行兌Q一赯出?BR> -- 最l查询结果,同样数据量,用时2U钟?BR> -- 对于q个旉来说Q我q是比较满意的。因为算的数据比较多了,而且和前面用游标用了27s
-- Ҏ(gu)׃是一个等量。不好坏,先可以拿出来见h了?/P>
-- 写入输出?q生成统计列?BR> insert into #sp_KHYEXYTJ_ReslutTable(dwmc,bqxs)
select dwmc,xsje from #sp_KHYEXYTJ_XSJE
-- 写入输出?BR> update #sp_KHYEXYTJ_ReslutTable
set #sp_KHYEXYTJ_ReslutTable.ssye = #sp_KHYEXYTJ_KHYE.khye
from #sp_KHYEXYTJ_KHYE
where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_KHYE.dwmc
--写入输出?BR> update #sp_KHYEXYTJ_ReslutTable
set #sp_KHYEXYTJ_ReslutTable.qmye = #sp_KHYEXYTJ_QMKHYE.QMkhye
from #sp_KHYEXYTJ_QMKHYE
where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_QMKHYE.dwmc
-- 写入输出?BR> update #sp_KHYEXYTJ_ReslutTable
set #sp_KHYEXYTJ_ReslutTable.ncye = #sp_KHYEXYTJ_NCYE.ncye
from #sp_KHYEXYTJ_NCYE
where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_NCYE.dwmc
-- 计算
update #sp_KHYEXYTJ_ReslutTable
set #sp_KHYEXYTJ_ReslutTable.khxye = isnull(xhkhda.khxye,0),
#sp_KHYEXYTJ_ReslutTable.cxye = abs(#sp_KHYEXYTJ_ReslutTable.ssye)-isnull(xhkhda.khxye,0)
from xhkhda
where #sp_KHYEXYTJ_ReslutTable.dwmc = xhkhda.dwmc
--最l输出结果了Q因为都是算得金额了Qؓ(f)了减误差,在计的时?BR> -- 全部使用6位小敎ͼ在输出的时候,取了两位数来输?/P>
-- 输入?BR> select
rtrim(ltrim(dwmc)) as dwmc,
cast(round(isnull(ncye,0),2) as decimal(15,2)) as ncye,
cast(round(isnull(ssye,0),2) as decimal(15,2)) as ssye,
cast(round(isnull(bqxs,0),2) as decimal(15,2)) as bqxs,
cast(round(isnull(qmye,0),2) as decimal(15,2)) as qmye,
cast(round(isnull(khxye,0),2) as decimal(15,2)) as khxye,
cast(round(isnull(
case
when cxye<= 0 then 0
when cxye>0 then cxye
end,0),2) as decimal(15,2)) as cxye
from #sp_KHYEXYTJ_ReslutTable
GO
q三个存储过E写的比较ؕ啦,毕竟是我的第一个存储过E嘛。可以谅解的。不q以后就不能写这么ؕ的存储过E了Q否则不可饶恕?BR>
在这三个存储q程中有一些地方写的还是不h意,比方_(d)存储q程A调用存储q程BQ而存储过EB需要返回一个结果集供A使用。虽然用了一个(f)时表来作为存储用Q可是L象写OO一P把(f)时表或者结果集象对象一栯回出厅R记得在写这个地方的前一天偶然看了资料,可以把结果集攑ֈ游标中output出去。不q写的时候忘C在什么地方看到的了,又犯了懒Q所以干脆就直接使用一个(f)时表Q反正游标返回出来后Q也是要攑ֈ临时表里面去的嘛?/P>
E:\WINDOWS\my.ini |
[WinMySQLAdmin] Server=D:/mysql/bin/mysqld-nt.exe [mysqld] basedir=D:/mysql datadir=D:/mysql-data/data |
E:\WINDOWS\my.ini |
[WinMySQLAdmin]
Server=D:/mysql/bin/mysqld-nt.exe [mysqld] basedir=D:/mysql datadir=D:/mysql-data/data default-character-set=gbk [client] default-character-set=gbk |