﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-路漫漫其修远兮，吾将上下而求索</title><link>http://www.cnitblog.com/ma3qiang2/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 05:57:19 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 05:57:19 GMT</pubDate><ttl>60</ttl><item><title>转载[数据库查询匹配]</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/05/05/43371.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Mon, 05 May 2008 07:09:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/05/05/43371.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/43371.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/05/05/43371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/43371.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/43371.html</trackback:ping><description><![CDATA[ CI     = Case Insensitive (大文字小文字を区別しない)<br />CS    = Case Sensitive (大文字小文字を区別する)<br />AI    = Accent Insensitive (清音濁音半濁音を区別しない)<br />AS    = Accent Sensitive (清音濁音半濁音を区別する)<br />KI    = Kana Insensitive (片仮名平仮名を区別しない)<br />KS    = Kana Sensitive (片仮名平仮名を区別する)<br />WI    = Width Insensitive (全角半角を区別しない)<br />WS    = Width Sensitive (全角半角を区別する)<br /><br /><p>我们都知道SQL Server查询过程中，单引号“'”是特殊字符，所以在查询的时候要转换成双单引号“''”。<br />但这只是特殊字符的一个，在实际项目中，发现对于like操作还有以下特殊字符：下划线“_”，百分号“%”，方括号“[]”以及尖号“^”。<br />其用途如下：<br />下划线：用于代替一个任意字符（相当于正则表达式中的 ? ）<br />百分号：用于代替任意数目的任意字符（相当于正则表达式中的 * ）<br />方括号：用于转义（事实上只有左方括号用于转义，右方括号使用<strong style="COLOR: red">最近优先原则</strong>匹配最近的左方括号）<br />尖号：用于排除一些字符进行匹配（这个与正则表达式中的一样）</p><p>以下是一些匹配的举例，需要说明的是，<span style="COLOR: red"><strong>只有like操作才有这些特殊字符，=操作是没有的</strong></span>。<br />a_b...        a[_]b%<br />a%b...       a[%]b%<br />a[b...       a[[]b%<br />a]b...       a]b%<br />a[]b...      a[[]]b%<br />a[^]b...     a[[][^]]b%<br />a[^^]b...    a[[][^][^]]b%</p><p>在实际进行处理的时候，对于=操作，我们一般只需要如此替换：<br />' -&gt; ''<br />对于like操作，需要进行以下替换（注意顺序也很重要）<br />[ -&gt; [[]     <strong style="COLOR: red">(这个必须是第一个替换的!!)</strong><br />% -&gt; [%]    (这里%是指希望匹配的字符本身包括的%而不是专门用于匹配的通配符)<br />_ -&gt; [_]<br />^ -&gt; [^]</p><img src ="http://www.cnitblog.com/ma3qiang2/aggbug/43371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-05-05 15:09 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/05/05/43371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库设计上下 [转载]</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/04/25/42714.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Fri, 25 Apr 2008 00:15:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/04/25/42714.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/42714.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/04/25/42714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/42714.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/42714.html</trackback:ping><description><![CDATA[    说到数据库，我认为不能不先谈数据结构。1996年，在我初入大学学习计算机编程时，当时的老师就告诉我们说：计算机程序＝数据结构＋算法。尽管现在的程序开发已由面向过程为主逐步过渡到面向对象为主，但我还是深深赞同8年前老师的告诉我们的公式：计算机程序＝数据结构＋算法。面向对象的程序开发，要做的第一件事就是，先分析整个程序中需处理的数据，从中提取出抽象模板，以这个抽象模板设计类，再在其中逐步添加处理其数据的函数(即算法)，最后，再给类中的数据成员和函数划分访问权限，从而实现封装。 <br />　　数据库的最初雏形据说源自美国一个奶牛场的记账薄(纸质的，由此可见，数据库并不一定是存储在电脑里的数据^_^)，里面记录的是该奶牛场的收支账目，程序员在将其整理、录入到电脑中时从中受到启发。当按照规定好的数据结构所采集到的数据量大到一定程度后，出于程序执行效率的考虑，程序员将其中的检索、更新维护等功能分离出来，做成单独调用的模块，这个模块后来就慢慢发展、演变成现在我们所接触到的数据库管理系统(DBMS)——程序开发中的一个重要分支。<br /><br />　　下面进入正题，首先按我个人所接触过的程序给数据库设计人员的功底分一下类： <br />　　１、没有系统学习过数据结构的程序员。这类程序员的作品往往只是他们的即兴玩具，他们往往习惯只设计有限的几个表，实现某类功能的数据全部塞在一个表中，各表之间几乎毫无关联。网上不少的免费管理软件都是这样的东西，当程序功能有限，数据量不多的时候，其程序运行起来没有什么问题，但是如果用其管理比较重要的数据，风险性非常大。 <br />　　２、系统学习过数据结构，但是还没有开发过对程序效率要求比较高的管理软件的程序员。这类人多半刚从学校毕业不久，他们在设计数据库表结构时，严格按照教科书上的规定，死扣E-R图和3NF(别灰心，所有的数据库设计高手都是从这一步开始的)。他们的作品，对于一般的access型轻量级的管理软件，已经够用。但是一旦该系统需要添加新功能，原有的数据库表差不多得进行大换血。 <br />　　３、第二类程序员，在经历过数次程序效率的提升，以及功能升级的折腾后，终于升级成为数据库设计的老鸟，第一类程序员眼中的高人。这类程序员可以胜任二十个表以上的中型商业数据管理系统的开发工作。他们知道该在什么样的情况下保留一定的冗余数据来提高程序效率，而且其设计的数据库可拓展性较好，当用户需要添加新功能时，原有数据库表只需做少量修改即可。 <br />　　４、在经历过上十个类似数据库管理软件的重复设计后，第三类程序员中坚持下来没有转行，而是希望从中找出“偷懒”窍门的有心人会慢慢觉悟，从而完成量变到质变的转换。他们所设计的数据库表结构有一定的远见，能够预测到未来功能升级所需要的数据，从而预先留下伏笔。这类程序员目前大多晋级成数据挖掘方面的高级软件开发人员。 <br />　　５、第三类程序员或第四类程序员，在对现有的各家数据库管理系统的原理和开发都有一定的钻研后，要么在其基础上进行二次开发，要么自行开发一套有自主版权的通用数据库管理系统。 <br /><br />　　我个人正处于第三类的末期，所以下面所列出的一些设计技巧只适合第二类和部分第三类数据库设计人员。同时，由于我很少碰到有兴趣在这方面深钻下去的同行，所以文中难免出现错误和遗漏，在此先行声明，欢迎大家指正，不要藏私哦8)<br /><br />　　一、树型关系的数据表 <br />　　不少程序员在进行数据库设计的时候都遇到过树型关系的数据，例如常见的类别表，即一个大类，下面有若干个子类，某些子类又有子类这样的情况。当类别不确定，用户希望可以在任意类别下添加新的子类，或者删除某个类别和其下的所有子类，而且预计以后其数量会逐步增长，此时我们就会考虑用一个数据表来保存这些数据。按照教科书上的教导，第二类程序员大概会设计出类似这样的数据表结构： <br /><br />类别表_1(Type_table_1) <br />名称　　　　　类型　　　　约束条件　　　说明 <br />type_id 　 int 　 无重复　　 类别标识，主键 <br />type_name　　 char(50) 不允许为空 类型名称，不允许重复 <br />type_father int 不允许为空 该类别的父类别标识，如果是顶节点的话设定为某个唯一值 <br /><br />　　这样的设计短小精悍，完全满足3NF，而且可以满足用户的所有要求。是不是这样就行呢？答案是NO！Why？<br /><br />　　我们来估计一下用户希望如何罗列出这个表的数据的。对用户而言，他当然期望按他所设定的层次关系一次罗列出所有的类别，例如这样： <br />总类别 <br />　　类别1 <br />　　　　类别1.1 <br />　　　　　　类别1.1.1 <br />　　　　类别1.2 <br />　　类别2 <br />　　　　类别2.1 <br />　　类别3 <br />　　　　类别3.1 <br />　　　　类别3.2 <br />　　…… <br /><br />　　看看为了实现这样的列表显示(树的先序遍历)，要对上面的表进行多少次检索？注意，尽管类别1.1.1可能是在类别3.2之后添加的记录，答案仍然是N 次。这样的效率对于少量的数据没什么影响，但是日后类型扩充到数十条甚至上百条记录后，单单列一次类型就要检索数十次该表，整个程序的运行效率就不敢恭维了。或许第二类程序员会说，那我再建一个临时数组或临时表，专门保存类型表的先序遍历结果，这样只在第一次运行时检索数十次，再次罗列所有的类型关系时就直接读那个临时数组或临时表就行了。其实，用不着再去分配一块新的内存来保存这些数据，只要对数据表进行一定的扩充，再对添加类型的数量进行一下约束就行了，要完成上面的列表只需一次检索就行了。下面是扩充后的数据表结构：<br /><br />类别表_2(Type_table_2) <br />名称　　　　　类型　　　　约束条件　　　 说明 <br />type_id 　 int 　 无重复　　 类别标识，主键 <br />type_name　　 char(50) 不允许为空 类型名称，不允许重复 <br />type_father int 不允许为空 该类别的父类别标识，如果是顶节点的话设定为某个唯一值 <br />type_layer char(6) 限定3层,初始值为000000 类别的先序遍历，主要为减少检索数据库的次数 <br /><br />　　按照这样的表结构，我们来看看上面例子记录在表中的数据是怎样的：<br /><br />type_id type_name type_father type_layer <br />1 总类别 0 000000 <br />2 类别1 1 010000 <br />3 类别1.1 2 010100 <br />4 类别1.2 2 010200 <br />5 类别2 1 020000 <br />6 类别2.1 5 020100 <br />7 类别3 1 030000 <br />8 类别3.1 7 030100 <br />9 类别3.2 7 030200 <br />10 类别1.1.1 3 010101 <br />…… <br /><br />　　现在按type_layer的大小来检索一下：select * FROM Type_table_2 ORDER BY type_layer<br /><br />列出记录集如下：<br /><br />type_id type_name type_father type_layer <br />1 总类别 0 000000 <br />2 类别1 1 010000 <br />3 类别1.1 2 010100 <br />10 类别1.1.1 3 010101 <br />4 类别1.2 2 010200 <br />5 类别2 1 020000 <br />6 类别2.1 5 020100 <br />7 类别3 1 030000 <br />8 类别3.1 7 030100 <br />9 类别3.2 7 030200 <br />…… <br /><br />　　现在列出的记录顺序正好是先序遍历的结果。在控制显示类别的层次时，只要对type_layer字段中的数值进行判断，每2位一组，如大于0则向右移2 个空格。当然，我这个例子中设定的限制条件是最多3层，每层最多可设99个子类别，只要按用户的需求情况修改一下type_layer的长度和位数，即可更改限制层数和子类别数。其实，上面的设计不单单只在类别表中用到，网上某些可按树型列表显示的论坛程序大多采用类似的设计。<br /><br />　　或许有人认为，Type_table_2中的type_father字段是冗余数据，可以除去。如果这样，在插入、删除某个类别的时候，就得对  type_layer 的内容进行比较繁琐的判定，所以我并没有消去type_father字段，这也正符合数据库设计中适当保留冗余数据的来降低程序复杂度的原则，后面我会举一个故意增加数据冗余的案例。<br /><br />　　 <br />　　二、商品信息表的设计 <br />　　假设你是一家百货公司电脑部的开发人员，某天老板要求你为公司开发一套网上电子商务平台，该百货公司有数千种商品出售，不过目前仅打算先在网上销售数十种方便运输的商品，当然，以后可能会陆续在该电子商务平台上增加新的商品出售。现在开始进行该平台数据库的商品信息表的设计。每种出售的商品都会有相同的属性，如商品编号，商品名称，商品所属类别，相关信息，供货厂商，内含件数，库存，进货价，销售价，优惠价。你很快就设计出4个表：商品类型表 (Wares_type)，供货厂商表(Wares_provider)，商品信息表(Wares_info)： <br /><br />商品类型表(Wares_type) <br />名称　　　　　类型　　　　约束条件　　　 说明 <br />type_id 　 int 　 无重复　　 类别标识，主键 <br />type_name　　 char(50) 不允许为空 类型名称，不允许重复 <br />type_father int 不允许为空 该类别的父类别标识，如果是顶节点的话设定为某个唯一值 <br />type_layer char(6) 限定3层,初始值为000000 类别的先序遍历，主要为减少检索数据库的次数 <br /><br />供货厂商表(Wares_provider) <br />名称　　　　　类型　　　　约束条件　　　 说明 <br />provider_id int 　 无重复　　 供货商标识，主键 <br />provider_name char(100) 不允许为空 供货商名称 <br /><br />商品信息表(Wares_info) <br />名称　　　　 类型　　　　约束条件　　　 说明 <br />wares_id int 　 无重复　　 商品标识，主键 <br />wares_name char(100) 不允许为空 商品名称 <br />wares_type　　 int 不允许为空　　　　 商品类型标识，和Wares_type.type_id关联 <br />wares_info char(200) 允许为空 相关信息 <br />provider int 不允许为空 供货厂商标识，和Wares_provider.provider_id关联 <br />setnum int 初始值为1 内含件数，默认为1 <br />stock int 初始值为0 库存，默认为0 <br />buy_price money 不允许为空 进货价 <br />sell_price money 不允许为空 销售价 <br />discount money 不允许为空 优惠价 <br /><br />　　你拿着这3个表给老板检查，老板希望能够再添加一个商品图片的字段，不过只有一部分商品有图片。OK，你在商品信息表(Wares_info)中增加了一个haspic的BOOL型字段，然后再建了一个新表——商品图片表(Wares_pic)：<br /><br />商品图片表(Wares_pic) <br />名称　　　　 类型　　　　约束条件　　　 说明 <br />pic_id int 　 无重复　　 商品图片标识，主键 <br />wares_id int 不允许为空 所属商品标识，和Wares_info.wares_id关联 <br />pic_address　 char(200) 不允许为空　　　　　　　　　　 图片存放路径 <br /><br />　　程序开发完成后，完全满足老板目前的要求，于是正式启用。一段时间后，老板打算在这套平台上推出新的商品销售，其中，某类商品全部都需添加“长度”的属性。第一轮折腾来了……当然，你按照添加商品图片表的老方法，在商品信息表(Wares_info)中增加了一个haslength的BOOL型字段，又建了一个新表——商品长度表(Wares_length)：<br /><br />商品长度表(Wares_length) <br />名称　　　　 类型　　　　约束条件　　　 说明 <br />length_id int 　 无重复　　 商品图片标识，主键 <br />wares_id int 不允许为空 所属商品标识，和Wares_info.wares_id关联 <br />length　 char(20) 不允许为空　　　　　　　　　　 商品长度说明 <br /><br />　　刚刚改完没多久，老板又打算上一批新的商品，这次某类商品全部需要添加“宽度”的属性。你咬了咬牙，又照方抓药，添加了商品宽度表  (Wares_width)。又过了一段时间，老板新上的商品中有一些需要添加“高度”的属性，你是不是开始觉得你所设计的数据库按照这种方式增长下去，很快就能变成一个迷宫呢？那么，有没有什么办法遏制这种不可预见性，但却类似重复的数据库膨胀呢？我在阅读《敏捷软件开发：原则、模式与实践》中发现作者举过类似的例子：7.3　“Copy”程序。其中，我非常赞同敏捷软件开发这个观点：在最初几乎不进行预先设计，但是一旦需求发生变化，此时作为一名追求卓越的程序员，应该从头审查整个架构设计，在此次修改中设计出能够满足日后类似修改的系统架构。下面是我在需要添加“长度”的属性时所提供的修改方案：<br /><br />　　去掉商品信息表(Wares_info)中的haspic字段，添加商品额外属性表(Wares_ex_property)和商品额外信息表(Wares_ex_info)2个表来完成添加新属性的功能。<br /><br />商品额外属性表(Wares_ex_property) <br />名称　　　　 类型　　　　约束条件　　　 说明 <br />ex_pid int 　 无重复　　 商品额外属性标识，主键 <br />p_name char(20) 不允许为空 额外属性名称 <br /><br />商品额外信息表(Wares_ex_info) <br />名称　　　　 类型　　　　约束条件　　　 说明 <br />ex_iid int 　 无重复　　 商品额外信息标识，主键 <br />wares_id int 不允许为空 所属商品标识，和Wares_info.wares_id关联 <br />property_id　 int 不允许为空　　　　　　　　　　 商品额外属性标识，和Wares_ex_property.ex_pid关联 <br />property_value char(200) 不允许为空 商品额外属性值 <br /><br />　　在商品额外属性表(Wares_ex_property)中添加2条记录： <br />ex_pid p_name <br />1 商品图片 <br />2 商品长度 <br /><br />　　再在整个电子商务平台的后台管理功能中追加一项商品额外属性管理的功能，以后添加新的商品时出现新的属性，只需利用该功能往商品额外属性表  (Wares_ex_property)中添加一条记录即可。不要害怕变化，被第一颗子弹击中并不是坏事，坏的是被相同轨道飞来的第二颗、第三颗子弹击中。第一颗子弹来得越早，所受的伤越重，之后的抵抗力也越强8)<br /><br /><br />　　三、多用户及其权限管理的设计 <br />　　开发数据库管理类的软件，不可能不考虑多用户和用户权限设置的问题。尽管目前市面上的大、中型的后台数据库系统软件都提供了多用户，以及细至某个数据库内某张表的权限设置的功能，我个人建议：一套成熟的数据库管理软件，还是应该自行设计用户管理这块功能，原因有二： <br />　　1.那些大、中型后台数据库系统软件所提供的多用户及其权限设置都是针对数据库的共有属性，并不一定能完全满足某些特例的需求； <br />　　2.不要过多的依赖后台数据库系统软件的某些特殊功能，多种大、中型后台数据库系统软件之间并不完全兼容。否则一旦日后需要转换数据库平台或后台数据库系统软件版本升级，之前的架构设计很可能无法重用。 <br /><br />　　下面看看如何自行设计一套比较灵活的多用户管理模块，即该数据库管理软件的系统管理员可以自行添加新用户，修改已有用户的权限，删除已有用户。首先，分析用户需求，列出该数据库管理软件所有需要实现的功能；然后，根据一定的联系对这些功能进行分类，即把某类用户需使用的功能归为一类；最后开始建表： <br />　　 <br />功能表(Function_table) <br />名称　　类型　 约束条件　　　说明 <br />f_id int 　 无重复　　 功能标识，主键 <br />f_name char(20) 不允许为空 功能名称，不允许重复 <br />f_desc char(50) 允许为空 功能描述 <br /><br />用户组表(User_group) <br />名称　　 类型　 约束条件　　　说明 <br />group_id int 无重复 用户组标识，主键 <br />group_name char(20) 不允许为空 用户组名称 <br />group_power char(100) 允许为空 用户组权限表，内容为功能表f_id的集合 <br /><br />用户表(User_table) <br />名称　　　　类型　　　　约束条件　　　说明 <br />user_id int 无重复 用户标识，主键 <br />user_name char(20) 无重复 用户名 <br />user_pwd char(20) 不允许为空 用户密码 <br />user_type int 不允许为空 所属用户组标识，和User_group.group_id关联 <br /><br />　　采用这种用户组的架构设计，当需要添加新用户时，只需指定新用户所属的用户组；当以后系统需要添加新功能或对旧有功能权限进行修改时，只用操作功能表和用户组表的记录，原有用户的功能即可相应随之变化。当然，这种架构设计把数据库管理软件的功能判定移到了前台，使得前台开发相对复杂一些。但是，当用户数较大(10人以上)，或日后软件升级的概率较大时，这个代价是值得的。<br /><br /><br />　　四、简洁的批量m:n设计 <br />　　碰到m:n的关系，一般都是建立3个表，m一个，n一个，m:n一个。但是，m:n有时会遇到批量处理的情况，例如到图书馆借书，一般都是允许用户同时借阅n本书，如果要求按批查询借阅记录，即列出某个用户某次借阅的所有书籍，该如何设计呢？让我们建好必须的3个表先： <br /><br />书籍表(Book_table) <br />名称　　　类型　　　　约束条件　　　说明 <br />book_id int 无重复 书籍标识，主键 <br />book_no char(20) 无重复 书籍编号 <br />book_name char(100) 不允许为空 书籍名称 <br />…… <br /><br />借阅用户表(Renter_table) <br />名称　　　　类型　　　　约束条件　　　说明 <br />renter_id int 无重复 用户标识，主键 <br />renter_name char(20) 不允许为空 用户姓名 <br />…… <br /><br />借阅记录表(Rent_log) <br />名称　　　类型　　　　约束条件　　　说明 <br />rent_id int 无重复 借阅记录标识，主键 <br />r_id int 不允许为空 用户标识，和Renter_table.renter_id关联 <br />b_id int 不允许为空 书籍标识，和Book_table.book_id关联 <br />rent_date datetime 不允许为空 借阅时间 <br />…… <br /><br />　　为了实现按批查询借阅记录，我们可以再建一个表来保存批量借阅的信息，例如：<br /><br />批量借阅表(Batch_rent) <br />名称　　　类型　　　约束条件　　　说明 <br />batch_id int 无重复 批量借阅标识，主键 <br />batch_no int 不允许为空 批量借阅编号，同一批借阅的batch_no相同 <br />rent_id int 不允许为空 借阅记录标识，和Rent_log.rent_id关联 <br />batch_date datetime 不允许为空 批量借阅时间 <br /><br />　　这样的设计好吗？我们来看看为了列出某个用户某次借阅的所有书籍，需要如何查询？首先检索批量借阅表(Batch_rent)，把符合条件的的所有记录的rent_id字段的数据保存起来，再用这些数据作为查询条件带入到借阅记录表(Rent_log)中去查询。那么，有没有什么办法改进呢？下面给出一种简洁的批量设计方案，不需添加新表，只需修改一下借阅记录表(Rent_log)即可。修改后的记录表(Rent_log)如下：<br /><br />借阅记录表(Rent_log) <br />名称　　　类型　　　约束条件　　　说明 <br />rent_id int 无重复 借阅记录标识，主键 <br />r_id int 不允许为空 用户标识，和Renter_table.renter_id关联 <br />b_id int 不允许为空 书籍标识，和Book_table.book_id关联 <br />batch_no int 不允许为空 批量借阅编号，同一批借阅的batch_no相同 <br />rent_date datetime 不允许为空 借阅时间 <br />…… <br /><br />　　其中，同一次借阅的batch_no和该批第一条入库的rent_id相同。举例：假设当前最大rent_id是64，接着某用户一次借阅了3 本书，则批量插入的3条借阅记录的batch_no都是65。之后另外一个用户租了一套碟，再插入出租记录的rent_id是68。采用这种设计，查询批量借阅的信息时，只需使用一条标准T_SQL的嵌套查询即可。当然，这种设计不符合3NF，但是和上面标准的3NF设计比起来，哪一种更好呢？答案就不用我说了吧。<br /><br /><br />　　五、冗余数据的取舍 <br />　　上篇的“树型关系的数据表”中保留了一个冗余字段，这里的例子更进一步——添加了一个冗余表。先看看例子：我原先所在的公司为了解决员工的工作餐，和附近的一家小餐馆联系，每天吃饭记账，费用按人数平摊，月底由公司现金结算，每个人每个月的工作餐费从工资中扣除。当然，每天吃饭的人员和人数都不是固定的，而且，由于每顿工作餐的所点的菜色不同，每顿的花费也不相同。例如，星期一中餐5人花费40元，晚餐2人花费20，星期二中餐6人花费36元，晚餐3 人花费18元。为了方便计算每个人每个月的工作餐费，我写了一个简陋的就餐记账管理程序，数据库里有3个表： <br /><br />员工表(Clerk_table) <br />名称　　　　类型　　　　约束条件　　　说明 <br />clerk_id int 无重复 员工标识，主键 <br />clerk_name char(10) 不允许为空 员工姓名 <br /><br />每餐总表(Eatdata1) <br />名称　　　 类型　　　　约束条件　　　说明 <br />totle_id int 无重复 每餐总表标识，主键 <br />persons char(100) 不允许为空 就餐员工的员工标识集合 <br />eat_date datetime 不允许为空 就餐日期 <br />eat_type char(1) 不允许为空 就餐类型，用来区分中、晚餐 <br />totle_price money 不允许为空 每餐总花费 <br />persons_num int 不允许为空 就餐人数 <br /><br />就餐计费细表(Eatdata2) <br />名称　　类型　　约束条件　　　说明 <br />id int 无重复 就餐计费细表标识，主键 <br />t_id int 不允许为空 每餐总表标识，和Eatdata1.totle_id关联 <br />c_id int 不允许为空 员工标识标识，和Clerk_table.clerk_id关联 <br />price money 不允许为空 每人每餐花费 <br /><br />　　其中，就餐计费细表(Eatdata2)的记录就是把每餐总表(Eatdata1)的一条记录按就餐员工平摊拆开，是个不折不扣的冗余表。当然，也可以把每餐总表(Eatdata1)的部分字段合并到就餐计费细表(Eatdata2)中，这样每餐总表(Eatdata1)就成了冗余表，不过这样所设计出来的就餐计费细表重复数据更多，相比来说还是上面的方案好些。但是，就是就餐计费细表(Eatdata2)这个冗余表，在做每月每人餐费统计的时候，大大简化了编程的复杂度，只用类似这么一条查询语句即可统计出每人每月的寄餐次数和餐费总帐：<br /><br />select clerk_name AS personname,COUNT(c_id) as eattimes,SUM(price) AS ptprice FROM Eatdata2 join Clerk_tabsle ON (c_id=clerk_id) join eatdata1 ON (totleid=tid) where eat_date&gt;=CONVERT(datetime,'"&amp;the_date&amp;"') and eat_date <br /><br />　　想象一下，如果不用这个冗余表，每次统计每人每月的餐费总帐时会多麻烦，程序效率也够呛。那么，到底什么时候可以增加一定的冗余数据呢？我认为有2个原则：<br /><br />　　１、用户的整体需求。当用户更多的关注于，对数据库的规范记录按一定的算法进行处理后，再列出的数据。如果该算法可以直接利用后台数据库系统的内嵌函数来完成，此时可以适当的增加冗余字段，甚至冗余表来保存这些经过算法处理后的数据。要知道，对于大批量数据的查询，修改或删除，后台数据库系统的效率远远高于我们自己编写的代码。 <br />　　２、简化开发的复杂度。现代软件开发，实现同样的功能，方法有很多。尽管不必要求程序员精通绝大部分的开发工具和平台，但是还是需要了解哪种方法搭配哪种开发工具的程序更简洁，效率更高一些。冗余数据的本质就是用空间换时间，尤其是目前硬件的发展远远高于软件，所以适当的冗余是可以接受的。不过我还是在最后再强调一下：不要过多的依赖平台和开发工具的特性来简化开发，这个度要是没把握好的话，后期维护升级会栽大跟头的。<br /><br /><br /><img src ="http://www.cnitblog.com/ma3qiang2/aggbug/42714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-04-25 08:15 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/04/25/42714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C# decimal指定精度</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/04/14/42339.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Mon, 14 Apr 2008 02:31:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/04/14/42339.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/42339.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/04/14/42339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/42339.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/42339.html</trackback:ping><description><![CDATA[最近做一个项目。遇到了decimal 如何指定精度的问题<br />一般的指定参数<br />    param = new SqlParameter(ParamName, DbType);<br /><br />但decimal就不能只通过构造函数来解决了，你需要生成Parameters的实例通过实例来设置精度，比如：<br />SqlParameter par = new SqlParameter("@Quantity", SqlDbType.Decimal);<br />par.Precision = 18;<br />par.Scale = 3;<br />com.Parameters.Add(par);<br /><br /><br /><img src ="http://www.cnitblog.com/ma3qiang2/aggbug/42339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-04-14 10:31 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/04/14/42339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>prototype静态变量</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41911.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Thu, 03 Apr 2008 09:20:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41911.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/41911.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/41911.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/41911.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 角本中静态变量和普通变量可以同名&nbsp;&nbsp;<a href='http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41911.html'>阅读全文</a><img src ="http://www.cnitblog.com/ma3qiang2/aggbug/41911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-04-03 17:20 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JS对 CSS 的控制 且css学习网站</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41882.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Thu, 03 Apr 2008 02:13:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41882.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/41882.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/41882.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/41882.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 初学JS,惊奇的发现JS也可以对CSS进行控制&nbsp;&nbsp;<a href='http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41882.html'>阅读全文</a><img src ="http://www.cnitblog.com/ma3qiang2/aggbug/41882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-04-03 10:13 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/04/03/41882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ETL__Extraction-Transformation-Loading</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/03/21/41281.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Fri, 21 Mar 2008 01:37:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/03/21/41281.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/41281.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/03/21/41281.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/41281.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/41281.html</trackback:ping><description><![CDATA[ETL负责将分布的、异构数据源中的数据如关系数据、平面数据文件等抽取到临时中间层后进行清洗、转换、集成，最后加载到数据仓库或数据集市中，成为联机分析处理、数据挖掘的基础。<br><br>ETL是数据仓库中的非常重要的一环。它是承前启后的必要的一步。相对于关系数据库，数据仓库技术没有严格的数学理论基础，它更面向实际工程应用。所以从工程应用的角度来考虑，按着物理数据模型的要求加载数据并对数据进行一些系列处理，处理过程与经验直接相关，同时这部分的工作直接关系数据仓库中数据的质量，从而影响到联机分析处理和数据挖掘的结果的质量。<br><br>数据仓库是一个独立的数据环境，需要通过抽取过程将数据从联机事务处理环境、外部数据源和脱机的数据存储介质导入到数据仓库中；在技术上，ETL主要涉及到关联、转换、增量、调度和监控等几个方面；数据仓库系统中数据不要求与联机事务处理系统中数据实时同步，所以ETL可以定时进行。但多个ETL的操作时间、顺序和成败对数据仓库中信息的有效性至关重要。<br><br>　　ETL(Extract-Transform-Load的缩写，即数据抽取、转换、装载的过程)作为BI/DW（Business Intelligence）的核心和灵魂，能够按照统一的规则集成并提高数据的价值，是负责完成数据从数据源向目标数据仓库转化的过程，是实施数据仓库的重要步骤。如果说数据仓库的模型设计是一座大厦的设计蓝图，数据是砖瓦的话，那么ETL就是建设大厦的过程。在整个项目中最难部分是用户需求分析和模型设计，而ETL规则设计和实施则是工作量最大的，约占整个项目的60%～80%，这是国内外从众多实践中得到的普遍共识。<br><br>&nbsp; &nbsp;&nbsp; &nbsp;ETL是数据抽取（Extract）、转换（Transform）、清洗（Cleansing）、装载（Load）的过程。是构建数据仓库的重要一环，用户从数据源抽取出所需的数据，经过数据清洗,最终按照预先定义好的数据仓库模型，将数据加载到数据仓库中去。<br><br>　　信息是现代企业的重要资源，是企业运用科学管理、决策分析的基础。目前，大多数企业花费大量的资金和时间来构建联机事务处理OLTP的业务系统和办公自动化系统，用来记录事务处理的各种相关数据。据统计，数据量每2～3年时间就会成倍增长，这些数据蕴含着巨大的商业价值，而企业所关注的通常只占在总数据量的2％～4％左右。因此，企业仍然没有最大化地利用已存在的数据资源，以致于浪费了更多的时间和资金，也失去制定关键商业决策的最佳契机。于是，企业如何通过各种技术手段，并把数据转换为信息、知识，已经成了提高其核心竞争力的主要瓶颈。而ETL则是主要的一个技术手段。如何正确选择ETL工具？如何正确应用ETL？<br><br>　　目前，ETL工具的典型代表有:Informatica、Datastage、OWB、微软DTS&#8230;&#8230;<br><br>　　数据集成：快速实现ETL<br><br>　　ETL的质量问题具体表现为正确性、完整性、一致性、完备性、有效性、时效性和可获取性等几个特性。而影响质量问题的原因有很多，由系统集成和历史数据造成的原因主要包括:业务系统不同时期系统之间数据模型不一致；业务系统不同时期业务过程有变化；旧系统模块在运营、人事、财务、办公系统等相关信息的不一致；遗留系统和新业务、管理系统数据集成不完备带来的不一致性。<br><br>　　实现ETL，首先要实现ETL转换的过程。它可以集中地体现为以下几个方面：<br><br>　　空值处理 可捕获字段空值，进行加载或替换为其他含义数据，并可根据字段空值实现分流加载到不同目标库。<br><br>　　规范化数据格式 可实现字段格式约束定义，对于数据源中时间、数值、字符等数据，可自定义加载格式。<br><br>　　拆分数据 依据业务需求对字段可进行分解。例，主叫号 861084613409，可进行区域码和电话号码分解。<br><br>　　验证数据正确性 可利用Lookup及拆分功能进行数据验证。例如，主叫号861084613409，进行区域码和电话号码分解后，可利用Lookup返回主叫网关或交换机记载的主叫地区，进行数据验证。<br><br>　　数据替换 对于因业务因素，可实现无效数据、缺失数据的替换。<br><br>　　Lookup 查获丢失数据 Lookup实现子查询，并返回用其他手段获取的缺失字段，保证字段完整性。<br><br>　　建立ETL过程的主外键约束 对无依赖性的非法数据，可替换或导出到错误数据文件中，保证主键惟一记录的加载。<br><br>　　为了能更好地实现ETL，笔者建议用户在实施ETL过程中应注意以下几点：<br><br>　　第一，如果条件允许，可利用数据中转区对运营数据进行预处理，保证集成与加载的高效性；<br><br>　　第二，如果ETL的过程是主动&#8220;拉取&#8221;，而不是从内部&#8220;推送&#8221;，其可控性将大为增强；<br><br>　　第三，ETL之前应制定流程化的配置管理和标准协议；<br><br>　　第四，关键数据标准至关重要。目前，ETL面临的最大挑战是当接收数据时其各源数据的异构性和低质量。以电信为例，A系统按照统计代码管理数据，B系统按照账目数字管理，C系统按照语音ID管理。当ETL需要对这三个系统进行集成以获得对客户的全面视角时，这一过程需要复杂的匹配规则、名称/地址正常化与标准化。而ETL在处理过程中会定义一个关键数据标准，并在此基础上，制定相应的数据接口标准。<br><br>　　ETL过程在很大程度上受企业对源数据的理解程度的影响，也就是说从业务的角度看数据集成非常重要。一个优秀的ETL设计应该具有如下功能：<br><br>　　管理简单；采用元数据方法，集中进行管理；接口、数据格式、传输有严格的规范；尽量不在外部数据源安装软件；数据抽取系统流程自动化，并有自动调度功能；抽取的数据及时、准确、完整；可以提供同各种数据系统的接口，系统适应性强；提供软件框架系统，系统功能改变时，应用程序很少改变便可适应变化；可扩展性强。<br><br><br>　　数据模型：标准定义数据<br><br><br>　　合理的业务模型设计对ETL至关重要。数据仓库是企业惟一、真实、可靠的综合数据平台。数据仓库的设计建模一般都依照三范式、星型模型、雪花模型，无论哪种设计思想，都应该最大化地涵盖关键业务数据，把运营环境中杂乱无序的数据结构统一成为合理的、关联的、分析型的新结构，而ETL则会依照模型的定义去提取数据源，进行转换、清洗，并最终加载到目标数据仓库中。<br><br>　　模型的重要之处在于对数据做标准化定义，实现统一的编码、统一的分类和组织。标准化定义的内容包括：标准代码统一、业务术语统一。ETL依照模型进行初始加载、增量加载、缓慢增长维、慢速变化维、事实表加载等数据集成，并根据业务需求制定相应的加载策略、刷新策略、汇总策略、维护策略。<br><br><br>　　元数据：拓展新型应用<br><br><br>　　对业务数据本身及其运行环境的描述与定义的数据，称之为元数据（metadata）。元数据是描述数据的数据。从某种意义上说，业务数据主要用于支持业务系统应用的数据，而元数据则是企业信息门户、客户关系管理、数据仓库、决策支持和B2B等新型应用所不可或缺的内容。<br><br>　　元数据的典型表现为对象的描述，即对数据库、表、列、列属性（类型、格式、约束等）以及主键/外部键关联等等的描述。特别是现行应用的异构性与分布性越来越普遍的情况下，统一的元数据就愈发重要了。&#8220;信息孤岛&#8221;曾经是很多企业对其应用现状的一种抱怨和概括，而合理的元数据则会有效地描绘出信息的关联性。<br><br>　　而元数据对于ETL的集中表现为：定义数据源的位置及数据源的属性、确定从源数据到目标数据的对应规则、确定相关的业务逻辑、在数据实际加载前的其他必要的准备工作，等等，它一般贯穿整个数据仓库项目，而ETL的所有过程必须最大化地参照元数据，这样才能快速实现ETL。<br><br>　　ETL体系结构<br><br>　　下图为ETL体系结构，它体现了主流ETL产品框架的主要组成部分。ETL是指从源系统中提取数据，转换数据为一个标准的格式，并加载数据到目标数据存储区，通常是数据仓库。<br><br>　　ETL体系结构图<br><br>　　Design manager 提供一个图形化的映射环境，让开发者定义从源到目标的映射关系、转换、处理流程。设计过程的各对象的逻辑定义存储在一个元数据资料库中。<br><br>　　Meta data management 提供一个关于ETL设计和运行处理等相关定义、管理信息的元数据资料库。ETL引擎在运行时和其它应用都可参考此资料库中的元数据。<br><br>　　Extract 通过接口提取源数据，例如ODBC、专用数据库接口和平面文件提取器，并参照元数据来决定数据的提取及其提取方式。<br><br>　　Transform 开发者将提取的数据，按照业务需要转换为目标数据结构，并实现汇总。<br><br>　　Load 加载经转换和汇总的数据到目标数据仓库中，可实现SQL或批量加载。<br><br>　　Transport services 利用网络协议或文件协议，在源和目标系统之间移动数据，利用内存在ETL处理的各组件中移动数据。<br><br>　　Administration and operation 可让管理员基于事件和时间进行调度、运行、监测ETL作业、管理错误信息、从失败中恢复和调节从源系统的输出。
<img src ="http://www.cnitblog.com/ma3qiang2/aggbug/41281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-03-21 09:37 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/03/21/41281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>备份</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/03/11/40789.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Tue, 11 Mar 2008 08:34:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/03/11/40789.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/40789.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/03/11/40789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/40789.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/40789.html</trackback:ping><description><![CDATA[<p>实例（联机帮助）<br>某个站点在星期天晚上执行完整数据库备份。<br>在白天每隔 4 小时制作一个事务日志备份集，并用当天的备份重写头一天的备份<br>每晚则进行差异备份<br>如果，数据库的某个数据磁盘在星期四上午 9:12 出现故障</p>
<p>则可以<br>1，备份当前事务日志。<br>2，还原从星期天晚上开始的数据库备份。<br>3，还原从星期三晚上开始的差异备份，将数据库前滚到这一时刻。<br>4，还原从早上 4 点到 8 点的事务日志备份，以将数据库前滚到早上 8 点。<br>5，还原故障之后的日志备份。这将使数据库前滚到故障发生的那一刻。 </p>
<p>&nbsp;</p>
<p><br>&nbsp;</p>
<img src ="http://www.cnitblog.com/ma3qiang2/aggbug/40789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-03-11 16:34 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/03/11/40789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sysname 用法</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40737.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Mon, 10 Mar 2008 08:33:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40737.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/40737.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40737.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/40737.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/40737.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 12pt">sysname 定义了可与&nbsp;SQL &nbsp; Server &nbsp; 一起使用的所有数据类型，功能上等于nvarchar(128)<br>具体可参考以下代码<br>declare @sysName sysname<br>set @sysName='5'<br>set @sysName=@sysName+'1'<br>print @sysName<br>--51<br>set @sysName='5'<br>set @sysName=@sysName+1<br>print @sysName<br>--6</span>
<img src ="http://www.cnitblog.com/ma3qiang2/aggbug/40737.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-03-10 16:33 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40737.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>表函数 内嵌表函数 标量函数</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40736.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Mon, 10 Mar 2008 08:22:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40736.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/40736.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40736.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/40736.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/40736.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 12pt">1 标量函数，返回一个值 FN <br>2 内嵌表函数，返回一个表，但是函数里只能写select语句&nbsp; IF<br>3 表函数，返回一个表，函数里可以写SQL语句&nbsp; TF<br>sysobjects系统表中，xtype或type字段</span>
<img src ="http://www.cnitblog.com/ma3qiang2/aggbug/40736.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-03-10 16:22 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40736.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>弱类型 强类型语言</title><link>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40714.html</link><dc:creator>马强</dc:creator><author>马强</author><pubDate>Mon, 10 Mar 2008 01:15:00 GMT</pubDate><guid>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40714.html</guid><wfw:comment>http://www.cnitblog.com/ma3qiang2/comments/40714.html</wfw:comment><comments>http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/ma3qiang2/comments/commentRss/40714.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/ma3qiang2/services/trackbacks/40714.html</trackback:ping><description><![CDATA[弱类型 VB Javascript等<br>强类型语言 C#<br>弱类型语言没有明显的类型，能随着环境不同，自动转换类型。
<img src ="http://www.cnitblog.com/ma3qiang2/aggbug/40714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/ma3qiang2/" target="_blank">马强</a> 2008-03-10 09:15 <a href="http://www.cnitblog.com/ma3qiang2/archive/2008/03/10/40714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>