精华内容
下载资源
问答
  • 结构化查询语句格式

    2014-09-19 20:31:57
    数据库(DataBase):存放数据的仓库;存放的是一张一张的,特别像Excel,...为什么数据库;  1.文件读写,归档读取数据需要一次把数据全部读出来,占内存  2.数据库查找数据效率很高,体现在查找数据,数据修改(增删改
    数据库(DataBase):存放数据的仓库;存放的是一张一张的表,特别像Excel,都以表格形式存放数据,可以创建多张表

        常见的数据库: sqlite ,access, MySQL,SqlServer, Oracle;


    为什么要用数据库;
        1.文件读写,归档读取数据需要一次把数据全部读出来,占内存
        2.数据库查找数据效率很高,体现在查找数据,数据修改(增删改查)
        
        SQL(structured Query Language )结构化查询语句,用于对数据库的操作语句(增删改查)
    SQL语句不区分大小写
        字符串需要加双引号或者单引号
        * : 代表所有
        Where:是条件(可以不写)
        主键: 是一条数据的唯一标识符,一张表里只能够有一个主键并且主键不能够重复,一般把主键名设置为"id",不需要赋值,会自动添加/创建表: create table 表名 (字段名 字段数据类型 是否为主键, 字段名 字段数据类型,字段名 字段数据类型,......)
        查: Select 字段 (或者是*) From 表名 Where 字段  = 值
        增: insert into 表名 (字段1,字段2,...) values (值1,值2,...)
        改: update 表名 set 字段 = 值 where 字段 = 值
        删: delete from 表名 where 字段 = 值
    展开全文
  • 转自:...因为有客户端,没事我们也没必要通过sql语句就读取而查找表结构之类的东西。但是在以下的一些情况中可能我们就要用到了。比如:1.要写一个实体生成器的时候,我们就得读取表的字段、类型...

    转自:http://www.xxling.com/blog/article/58.aspx

    一、为什么要读取表结构

    对于一个程序员的平常工作当中,我们常用的都是用来从数据库表中读取数据的sql,而对于表结构的读取就比较少用了。因为有客户端,没事我们也没必要通过sql语句就读取而查找表结构之类的东西。但是在以下的一些情况中可能我们就要用到了。比如:

    1.要写一个实体生成器的时候,我们就得读取表的字段、类型等等之类的东西;

    2.如果要做一个数据库管理系统,我们不仅要读取结构,我们还得知道怎么去添加和修改这些结构(不过添加和修改不在这篇文章的介绍内容内);

    当然还会有其他的一些用到的情况,这里就不一一列举了。

    二、怎么入手

    当我们想到要做读取表结构这件事时,我们该如何入手呢。如果我们已经是这方面的专家或已经熟悉了这方面的知识的话,那么我们需要的就是动手去做了。但如果你之前对这一无所知或者了解不够的时候,我们该怎么做呢?

    今天我们就说说第二种情况我们该怎么做吧。为什么要说这呢?因为每个人的知识都是有限的,而且不可能每一次在你需要的时候都有人在身边告诉你怎么去做,所以我们就要学会如何用手上可以用的资源来寻找到我们想要的东西。

    如果我们完全不知道的情况下,第一,我们可以把我们知道的关键字到搜索引擎去获取一些知识和答案,然后我们根据这些知识可以做进一步的检索或者根据自己已有的经验去引导自己去摸索和认识。第二,我们可以向身边有经验的同事或者同学询问。第三,我们也可以到一些技术论坛发帖提问来寻找答案。学会自己去找答案,这是很重要的,这是我为什么要啰嗦这一部分的原因。

    三、需求

    今天我们想要读取的结构包括:数据库中的所有用户表,表的字段名,字段类型,字段长度限制,字段描述,是否允许为空,是否为主键。

    四、有哪些方案

    这里我先说明一下,今天说的是sql server 2005及以上的版本,因为2000版本的会有一些差别,后面会提到。

    通过我们掌握的知识,我们知道,数据库表结构相关的元数据是存储在数据库的系统表里的。那我们先看数据库的表结构信息都可以在哪里找得到。

    首先打开我们要操作的数据库,展开视图中的系统视图选项,我们就可以看到一大堆的分别以INFORMATION_SCHEMA.XXX,sys.sysXXX和sys.XXX形式存在的视图。这些视图都是些什么呢?

    以INFORMATION_SCHEMA.XXX形式存在的视图我们称之为信息架构视图,它们是在系统表的基础上建立的一系列视图,提供了更加直观的结果。2000版本时是在master数据库中,而从2005版本开始,这些视图被移到了每个数据库中去了。其次这些视图是符合ISO标准的。

    以sys.sysXXX形式存在视图我们称之为兼容性视图,顾名思义这些视图就是为了向后兼容而存在的,在2000版本时这些视图就已经存在但未公开,只公开了在master中的系统表。2005版本之后公开了这些视图并放在每个数据库中。

    以sys.XXX形式存在的视图我们称之为目录视图,是2005版本之后弄出来的东东。

    那么具体这些视图中每个视图又都分别有什么数据呢?如果你手头有完整的介绍,那就直接看介绍就好。否则,首先我们可以通过它们的命名来判断它们存储的相关内容,其次我们可以将它们的结果搜索出来看看里面到底是什么东西,而对于每个字段是什么意思,我们可以通过F1去查找到相关的帮助文档。

    根据第三部分的需求,我们一一找到数据所在的位置,如下:
    数据库的用户表列表:sys.sysobjects或者sys.tables或者INFORMATION_SCHEMA.TABLES
    表的字段名:sys.syscolumns或者sys.columns或者INFORMATION_SCHEMA.COLUMNS
    字段类型:sys.syscolumns(加上sys.systypes)或者sys.columns(加上sys.types)或者INFORMATION_SCHEMA.COLUMNS
    字段长度:sys.syscolumns或者sys.columns或者INFORMATION_SCHEMA.COLUMNS
    字段描述:sys.extended_properties
    是否允许为空:sys.syscolumns或者sys.columns或者INFORMATION_SCHEMA.COLUMNS
    是否为主键:sys.sysobjects(加上sys.sysindexes和sys.sysindexkeys)或者sys.indexes(加上sys.index_columns)或者INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
    注:括号中的表都是需要他们联合才能拿到需要的信息的。比如sys.sysobjects没有与字段id建立关系,所以才加上sys.sysindexes和sys.sysindexkeys这两张表做桥梁来建立关系

    五、如何去选择

    首先,兼容性视图就是为了兼容而存在,而今天我们只考虑2005版本及以上的版本所以不在推荐使用,可以将它pass掉

    其次,我们知道INFORMATION信息架构视图里面的信息会更加的直观而且符合ISO标准,理论上这是我们不二的选择。但是从第四部分的结果可以看出,INFORMATION的视图中找不到我们需要的字段描述的信息(当然可以借助其他办法配合拿到相应的信息)。相反,目录视图中可以找到所有的信息,所以也是一种选择

    综上,我们应该选择信息架构视图或者目录视图。而信息结构视图的信息比较直观就不多说,这次主要是以目录视图来开讲,当然最终会给出三种方案的结果。

    六、具体实现

    1.读取数据库的所有表
    select name from sys.objects where type = 'U'
    或者
    select name from sys.tables where type = 'U'

    2.读取表结构

    首先,我们先找出表之间的关联以获取表联合的条件。

    所有表如下:
    sys.columns
    sys.types
    sys.extended_properties
    sys.objects(也可以用sys.tables,它是sys.objects派生表)
    sys.indexes
    sys.index_columns

    既然我们读取的是表结构,那么首先我们的限定范围就应该是表,所以我们先要找到table对应的id,所以我们先从sys.objects表开始。我们可以通过表名进行过滤得到所要表的id。代码如下:

    select object_id from sys.objects where name=@TableName

    @TableName为存储表名字的一变量,一下涉及到表名的地方都用该变量替代。该变量可按如下定义

    declare @TableName varchar(50)

    set @TableName='XXXX'

    得到了table的id我们就可以通过这id作为筛选条件来得到关于这张表的一些信息,可以用作where条件也可以通过join联合的方式,在这里我们选用join的方式吧。

    表字段的信息主要是存在sys.columns表,所以我们紧跟着就从这张表查找一部分信息,然后在联合其他表去查其他信息。

    在sys.columns中我们可以获得的需要的信息有字段名(name),字段类型的id(user_type_id),字段的限制长度(max_length),是否允许为空(is_nullable)。

    其中我们容易迷惑的有如下:

    (1)在读取字段类型时我们发现此表中有一个叫system_type_id的字段和一个user_type_id的字段,那他们之间有什么区别呢?顾名思义,前面一system为前缀的就是系统类型的id,而以user为前缀的就是用户类型的id,其中用户类型包含了系统类型,用户类型是基于系统类型的基础上的扩展。也就是说如果是系统类型,那么这两个字段的值就是一样的。所以这里我们就去用户类型id字段user_type_id。

    (2)我们再看看max_length字段,它是指可以存储的最大字节数。这是怎么理解呢,我们知道在系统类型中会有varchar和nvarchar之类的类型,如果是varchar那么我们定义字段是输入的长度是多少那么max_length字段显示的就是多少。而如果是nvarchar的话,那么一个字符会占两个字节,所以当我们定义字段的时候输入的长度是100的话,那么实际的最大字节数是200,max_length字段显示的就是200.

    下面我们通过sys.objects和sys.columns的联合即可拿到对应表的的列信息,代码如下

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    select
    col.name as ColumnName,
    col.max_length as DataLength,
    col.is_nullable as IsNullable
    from sys.objects obj
    inner join sys.columns col
    on obj.object_id=col.object_id
    where obj.name=@TableName

    至于是用left join,还是right join或者inner join这里的结果都是一样(因为左边是唯一的而且是存在的,只要右边的有列存在那么三种的结果是一样的),但为了更加严谨一点这里我们还是用inner join好一点。

    到这里我们其实拿到字段名、长度和是否为空的内容了,下面我再联合sys.types获取数据类型的名称。由之前的讨论结果,我们使用user_type_id这个字段进行联合。代码变成如下:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    declare @TableName varchar(50)
    set @TableName='TestTable'
    select
    col.name as ColumnName,
    col.max_length as DataLength,
    col.is_nullable as IsNullable,
    t.name as DataType
    from sys.objects obj
    inner join sys.columns col
    on obj.object_id=col.object_id
    left join sys.types t
    on t.user_type_id=col.user_type_id
    where obj.name=@TableName

    下一步我们就开始读取描述,字段的描述是做为扩展属性存在扩展属性表中。属性以键值对的方式存在,这里就是name和value。我们添加字段时直接添加的描述是以MS_Description为名字的属性存在,所以我们在扩展属性表中拿字段描述的话要同时以这名字作为筛选条件。我们也可以通过字段右键属性中的扩展属性选项来添加其他名字的属性,这些数据也存在该表中,但不属于今天的讲解范围就不多说了。另外除了这个筛选条件之外,我们要确定具体到某个字段的描述,我们还得知道对应的表id和字段id,他们在扩展属性表中分别对应于major_id和minor_id。下面是添加了获取属性后的代码:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    declare @TableName varchar(50)
    set @TableName='TestTable'
    select
    col.name as ColumnName,
    col.max_length as DataLength,
    col.is_nullable as IsNullable,
    t.name as DataType,
    ep.value as Description
    from sys.objects obj
    inner join sys.columns col
    on obj.object_id=col.object_id
    left join sys.types t
    on t.user_type_id=col.user_type_id
    left join sys.extended_properties ep
    on ep.major_id=obj.object_id
    and ep.minor_id=col.column_id
    and ep.name='MS_Description'
    where obj.name=@TableName

    经过上面的努力我们要的信息都快全了,就剩下是否为主键,之所以把这个放在最后讲,是因为这个的获取没那么直接,它涉及到了sys.indexes和sys.index_columns两张表。在sys.indexes表中就有是否为主键的信息(对应字段为is_primary_key),但是它只跟表id(object_id)有直接的关联,要涉及到具体的字段我们还得联合sys.index_columns表。我们先通过sys.index_columns的object_id和column_id来筛选出具体的字段,然后在通过ic.index_id去sys.indexes来找到相应的记录来确定是否为主键。另外由于一字段可能有多个索引,所以我们还需要通过名字是否已PK_开头来做进一步的限定。修改后的代码如下:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    select
    col.name as ColumnName,
    col.max_length as DataLength,
    col.is_nullable as IsNullable,
    t.name as DataType,
    ep.value as Description,
    (
        select top 1 ind.is_primary_key from sys.index_columns ic
        left join sys.indexes ind
        on ic.object_id=ind.object_id
        and ic.index_id=ind.index_id
        and ind.name like 'PK_%'
        where ic.object_id=obj.object_id
        and ic.column_id=col.column_id
    as IsPrimaryKey
    from sys.objects obj
    inner join sys.columns col
    on obj.object_id=col.object_id
    left join sys.types t
    on t.user_type_id=col.user_type_id
    left join sys.extended_properties ep
    on ep.major_id=obj.object_id
    and ep.minor_id=col.column_id
    and ep.name='MS_Description'
    where obj.name=@TableName

    至此我们就拿到我们想要的所有信息了。

    七、注意的一些问题

    (1)第一个注意的问题如下(摘自官方网):

    在 SQL Server 的未来版本中,Microsoft 可能会通过在列列表的末尾添加列来扩充任何系统目录视图的定义。我们建议不要在生产代码中使用语法 SELECT * FROM sys.catalog_view_name,这是因为返回的列数可能会更改和中断应用程序。

    (2)Microsoft 建议不要直接查询系统表。而是应该使用视图进行查询。

    八、完整的代码示例

    下面给出了上面三种方案完整代码:

    目录视图的方式:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    select
    col.name as ColumnName,
    col.max_length as DataLength,
    col.is_nullable as IsNullable,
    t.name as DataType,
    ep.value as Description,
    (
        select top 1 ind.is_primary_key from sys.index_columns ic
        left join sys.indexes ind
        on ic.object_id=ind.object_id
        and ic.index_id=ind.index_id
        and ind.name like 'PK_%'
        where ic.object_id=obj.object_id
        and ic.column_id=col.column_id
    as IsPrimaryKey
    from sys.objects obj
    inner join sys.columns col
    on obj.object_id=col.object_id
    left join sys.types t
    on t.user_type_id=col.user_type_id
    left join sys.extended_properties ep
    on ep.major_id=obj.object_id
    and ep.minor_id=col.column_id
    and ep.name='MS_Description'
    where obj.name=@TableName

    信息架构视图的方式:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    select
    col.COLUMN_NAME as ColumnName,
    col.DATA_TYPE as DataType,
    col.CHARACTER_OCTET_LENGTH as DataLength,
    col.IS_NULLABLE as IsNullable,
    ccu.CONSTRAINT_NAME as IsPrimaryKey,
    de.value as Description
    from INFORMATION_SCHEMA.COLUMNS col
    left join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
    on ccu.TABLE_NAME=col.TABLE_NAME
    and ccu.COLUMN_NAME=col.COLUMN_NAME
    and ccu.CONSTRAINT_NAME like 'PK_%'
    left join ::fn_listextendedproperty (NULL'user''dbo''table', @TableName,'column'defaultas de
    on col.COLUMN_NAME = de.objname COLLATE Chinese_PRC_CI_AS
    where col.TABLE_NAME=@TableName

    由于信息架构视图里面没有存储扩展属性的相应视图,我们通过fn_listextendedproperty函数来获取,具体该函数的作用和使用可以百度之,这里就不多说了。

    兼容视图的方式:

    -收缩代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    select
    col.name as ColumnName,
    col.isnullable as IsNullable,
    col.length as DataLength,
    tp.name as DataType,
    ep.value as Descript,
    (
        select count(*) from sys.sysobjects
        where parent_obj=obj.id
        and name=(
            select top name from sys.sysindexes ind
            inner join sys.sysindexkeys indkey
            on ind.indid=indkey.indid
            and indkey.colid=col.colid
            and indkey.id=obj.id
            where ind.id=obj.id
            and ind.name like 'PK_%'
        )
    as IsPrimaryKey
    from sys.sysobjects obj
    inner join sys.syscolumns col
    on obj.id = col.id
    left join sys.systypes tp
    on col.xtype=tp.xusertype
    left join sys.extended_properties ep
    on ep.major_id=obj.id
    and ep.minor_id=col.colid
    and ep.name='MS_Description'
    where obj.name=@TableName

    说明:以上各种方案取出来的一些字段信息的类型没有统一一致,也没有将相应的null转为为0之类的,在使用中在根据自己的需要来添加一些判断转为就是了。如信息架构视图的方式中返回的IsPrimaryKey是以PK_XXX之类的信息存在。而目录视图中是以1和0来表示,不是的情况还可能为null,使用时可以将null也先转换为0.

    最后,以上如果有不对的地方或者因为疏忽没考虑不周到的地方或者有可以优化的地方欢迎指出和纠正。

    博主补充一个IsIdentity标志:

    1. select  
    2. col.name as ColumnName,  
    3. col.isnullable as IsNullable,  
    4. col.length as DataLength,  
    5. tp.name as DataType,  
    6. ep.value as Descript,  
    7. (  
    8.     select count(*) from sys.sysobjects  
    9.     where parent_obj=obj.id  
    10.     and name=(  
    11.         select top 1 name from sys.sysindexes ind  
    12.         inner join sys.sysindexkeys indkey  
    13.         on ind.indid=indkey.indid  
    14.         and indkey.colid=col.colid  
    15.         and indkey.id=obj.id  
    16.         where ind.id=obj.id  
    17.         and ind.name like 'PK_%'  
    18.     )  
    19. as IsPrimaryKey  
    20. ,  
    21. COLUMNPROPERTY(col.id,col.name,'IsIdentity'as IsIdentity  
    22. from sys.sysobjects obj  
    23. inner join sys.syscolumns col  
    24. on obj.id = col.id  
    25. left join sys.systypes tp  
    26. on col.xtype=tp.xusertype  
    27. left join sys.extended_properties ep  
    28. on ep.major_id=obj.id  
    29. and ep.minor_id=col.colid  
    30. and ep.name='MS_Description'  
    31. where obj.name=@TableName  


    展开全文
  • 驱动

    2014-01-02 09:22:53
    什么驱动(出处《代码大全》,对软件感兴趣者,此书值得一看) 驱动,又称之为驱动法、...驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信
    什么是表驱动(出处《代码大全》,对软件感兴趣者,此书值得一看)
    表驱动,又称之为表驱动法、表驱动方法。
    “表”是几乎所有数据结构课本都要讨论的非常有用的数据结构。表驱动方法出于特定的目的来使用表,程序员们经常谈到“表驱动”方法,但是课本中却从未提到过什么是"表驱动"方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,表就变得越来越富有吸引力了,通过下面的这个例子大家就能知道什么是所谓的表驱动方法了。
    假设你需要一个可以返回每个月中天数的函数(为简单起见不考虑闰年),
    一个比较笨的方法是一个大的if语句:
    int iGetMonthDays(int iMonth)
    {
    int iDays;
    if(1 == iMonth) {iDays = 31;}
    else if(2 == iMonth) {iDays = 28;}
    else if(3 == iMonth) {iDays = 31;}
    else if(4 == iMonth) {iDays = 30;}
    else if(5 == iMonth) {iDays = 31;}
    else if(6 == iMonth) {iDays = 30;}
    else if(7 == iMonth) {iDays = 31;}
    else if(8 == iMonth) {iDays = 31;}
    else if(9 == iMonth) {iDays = 30;}
    else if(10 == iMonth) {iDays = 31;}
    else if(11 == iMonth) {iDays = 30;}
    else if(12 == iMonth) {iDays = 31;}
    return iDays;
    }
    可以看出本来应该很简单的一件事情,代码却是这么冗余,解决这个的办法就可以用表驱动方法。
    static int aiMonthDays[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    // 我们可以先定义一个静态数组,这个数组用来保存一年十二个月的天数
    int iGetMonthDays(int iMonth)
    {
    return aiMonthDays[(iMonth - 1)];
    }
    接下来不用多说了,大家都能看出用这种表驱动的方法代替这种情逻辑性不强,但分支很多的代码是多么令人"赏心悦目"的了。
    函数:
    函数指针在表驱动方法中的应用
    在使用表驱动方法时需要说明的一个问题是,你将在表中存储些什么。
    在某些情况下,表查寻的结果是数据。如果是这种情况,你可以把数据存储在表中。
    在其它情况下,表查寻的结果是动作。在这种情况下,你可以把描述这一动作的代码存储在表中。
    在某些语言中,也可以把实现这一动作的子程序的调用存储在表中,也就是将函数的指针保存在表中,当查找到这项时,让程序用这个函数指针来调用相应的程序代码,这个就是函数指针在表驱动方法中的应用。
    其实说到这已经说了很多表驱动方法的相关问题了,现在要把函数指针也应用进去,很多人应该已经想到会是个什么样子了,其实也很简单,通过下面这两段伪代码的例子就可以充分体现函数指针在表驱动方法中应用会使代码更加精致。
    我们在写一段程序的过程中会经常遇到这样的问题,我们在写一个Task的主函数中有时会要等待不同的Event通知,并且处理不同的分支,首先有如下的Event Bit的宏定义和相应的处理函数的声明。
    #define TASK_EVENT_BIT00 (1 << 0)
    #define TASK_EVENT_BIT01 (1 << 1)
    #define TASK_EVENT_BIT02 (1 << 2)
    #define TASK_EVENT_BIT03 (1 << 3)
    #define TASK_EVENT_BIT04 (1 << 4)
    #define TASK_EVENT_BIT05 (1 << 5)
    #define TASK_EVENT_BIT06 (1 << 6)
    #define TASK_EVENT_BIT07 (1 << 7)
    #define TASK_EVENT_BIT08 (1 << 8)
    #define TASK_EVENT_BIT09 (1 << 9)
    void vDoWithEvent00();
    void vDoWithEvent01();
    void vDoWithEvent02();
    void vDoWithEvent03();
    void vDoWithEvent04();
    void vDoWithEvent05();
    void vDoWithEvent06();
    void vDoWithEvent07();
    void vDoWithEvent08();
    void vDoWithEvent09();
    我们一般首先想到的写法是
    unsigned long ulEventBit;
    for(;;)
    {
    xos_waitFlag(&ulEventBit);
    if(ulEventBit & TASK_EVENT_BIT00)
    {
    vDoWithEvent00();
    }
    if(ulEventBit & TASK_EVENT_BIT01)
    {
    vDoWithEvent01();
    }
    if(ulEventBit & TASK_EVENT_BIT02)
    {
    vDoWithEvent02();
    }
    if(ulEventBit & TASK_EVENT_BIT03)
    {
    vDoWithEvent03();
    }
    if(ulEventBit & TASK_EVENT_BIT04)
    {
    vDoWithEvent04();
    }
    if(ulEventBit & TASK_EVENT_BIT05)
    {
    vDoWithEvent05();
    }
    if(ulEventBit & TASK_EVENT_BIT06)
    {
    vDoWithEvent06();
    }
    if(ulEventBit & TASK_EVENT_BIT07)
    {
    vDoWithEvent07();
    }
    if(ulEventBit & TASK_EVENT_BIT08)
    {
    vDoWithEvent08();
    }
    if(ulEventBit & TASK_EVENT_BIT09)
    {
    vDoWithEvent09();
    }
    }
    可以看出这样写是不是显得程序太长了呢。
    下面我们再看看同样的一段代码用函数指针和表驱动方法结合的方法写出会是什么样子。
    typedef struct {
    unsigned long ulEventBit;
    void (*Func)(void);
    } EventDoWithTable_t;
    /* 定义EventBit 与相应处理函数关系的结构体 */
    static const EventDoWithTable_t astDoWithTable[] = {
    { TASK_EVENT_BIT00 , vDoWithEvent00},
    { TASK_EVENT_BIT01 , vDoWithEvent01},
    { TASK_EVENT_BIT02 , vDoWithEvent02},
    { TASK_EVENT_BIT03 , vDoWithEvent03},
    { TASK_EVENT_BIT04 , vDoWithEvent04},
    { TASK_EVENT_BIT05 , vDoWithEvent05},
    { TASK_EVENT_BIT06 , vDoWithEvent06},
    { TASK_EVENT_BIT07 , vDoWithEvent07},
    { TASK_EVENT_BIT08 , vDoWithEvent08},
    { TASK_EVENT_BIT09 , vDoWithEvent09}
    };
    /* 建立EventBit与相应处理函数的关系表 */
    ulong ulEventBit;
    int i;
    for(;;)
    {
    xos_waitFlag(&ulEventBit);
    for(i = 0 ; i < sizeof(astDoWithTable)/sizeof(astDoWithTable[0]); i ++)
    {
    if ( ( ulEventBit & astDoWithTable[i].ulEventBit ) &&
    ( astDoWithTable[i].Func != NULL ) )
    {
    (*astDoWithTable[i].Func)();
    /* 通过函数指针来调用相应的处理函数 */
    }
    }
    }
    可以看出这种代码的风格使代码变得精致得多了,并且使程序的灵活性大大加强了,如果我们还要再加入EventBit,只修改表中的内容就可以了。
    总结
    通过上面介绍的,相信大家已经对函数指针的使用方法有所了解了,但是需要提醒大家,凡事都要具体情况具体分析,使用函数指针的时候一定要多加小心,因为函数指针有它的一个致命的缺点。
    函数指针的致命缺点是:无法对参数 (parameter) 和返回值 (return value) 的类型进行检查,因为函数已经退化成指针,指针是不带有这些类型信息的。少了类型检查,当参数或者反回值不一致时,会造成严重的错误。有些编译器并不会帮我们找出函数指针这样的致命错误。所以,许多新的编程语言都不支持函数指针了,而改用其他方式。
    从上面的例3中我们可以看到
    int max(int x,int y){ return x>y?x:y; }
    int min(int x,int y){ return x<y?x:y; }
    int add(int x,int y){ return x+y; }
    这三个函数都有两个参数,而在后面却把处理函数定义成
    int process(int x,int y, int (*f)())
    {
    return (*f)(x,y);
    }
    其中第三个参数是一个函数的指针,从表面上看它是个没有参数,并且返回int型的函数的指针,但是在后面却用process(a,b,max)的方式进行调用,max带有两个参数,这段程序在C语言中就可以顺利的编译通过(但是在C++中却编译不通过),可以看出如果编译器没有检查出错误,而我们又不小心写错的话,后果是很严重的,比如return (*f)(x,y);不小心写成return (*f)(x);在C语言中可以正常的被编译通过,但是运行结果一定不是我们想要的。
    因此在C语言中使用函数指针的时候,一定要小心“类型陷阱”,小心地使用函数指针,只有这样我们才可以从函数指针中获益。
    展开全文
  • 老师说我的返回语句太多,让我改进,一句返回语句来表达。 我改成了这样,这个错误是什么,我该怎么改? return equals(n->left, t->left) && (equals(n->right, t->right)&&(n!=NULL&&t!=NULL&&n->data==t->...
  • 下面是关于数据库索引的相关知识: 简单来说,数据库索引就是数据库的数据结构!进一步说则是该数据结构中存储了一张中某一列的所有值,也就是说索引是基于数据中的...现在要执行下面这条查询语句查找出所...

    下面是关于数据库索引的相关知识:

    1. 简单来说,数据库索引就是数据库的数据结构!进一步说则是该数据结构中存储了一张表中某一列的所有值,也就是说索引是基于数据表中的某一列创建的。总而言之:一个索引是由表中某一列上的数据组成,并且这些数据存储在某个数据结构中。

    2.索引的作用。举个例子,假设有一张数据表Emplyee,该表有三列:

    表中有几万条记录。现在要执行下面这条查询语句,查找出所有名字叫“Jesus”的员工的详细信息

    3.如果没有数据库索引功能,数据库系统会逐行的遍历整张表,对于每一行都要检查其Employee_Name字段是否等于“Jesus”。因为我们要查找所有名字为“Jesus”的员工,所以当我们发现了一条名字是“Jesus”的记录后,并不能停止继续查找,因为可能有其他员工也叫“Jesus”。这就意味着,对于表中的几万条记录,数据库每一条都要检查。这就是所谓的“全表扫描”( full table scan)

    4.而数据库索引功能索引的最大作用就是加快查询速度,它能从根本上减少需要扫表的记录/行的数量。

    5.如何创建数据库索引。可以基于Employee表的两列创建索引即可:

    拓展资料:

    1. 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。

    2.索引的一个主要目的就是加快检索表中数据的方法,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID的辅助数据结构。

    3.索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)的值进行排序的结构。

    4.例如这样一个查询:select * from table1 where id=10000。如果没有索引,必须遍历整个表,直到ID等于10000的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),即可在索引中查找。由于索引是经过某种算法优化过的,因而查找次数要少的多。可见,索引是用来定位的。

    5.从数据搜索实现的角度来看,索引也是另外一类文件/记录,它包含着可以指示出相关数据记录的各种记录。其中,每一索引都有一个相对应的搜索码,字符段的任意一个子集都能够形成一个搜索码。这样,索引就相当于所有数据目录项的一个集合,它能为既定的搜索码值的所有数据目录项提供定位所需的各种有效支持

    参考资料:数据库索引-百度百科

    展开全文
  • 驱动编程

    2020-10-18 14:28:54
    驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的
  •  1、说明:复制(只复制结构,源表名:a 新表名:b) (Access可用)  法一:select * into b from a where 1<>1  法二:select top 0 * into b from a  2、说明:拷贝(拷贝数据,源表名:a 目标表名:b) (Access...
  • 驱动法

    2011-10-29 18:51:01
    驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随
  • 驱动法介绍

    千次阅读 2011-10-29 14:26:58
    什么驱动  驱动,又称之为驱动法、驱动方法...驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过来挑选。在简单的情况
  • 什么驱动法 ...驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。 数据用法 假设你需要一个可以返回每个月中天数的函数(为简单起见不考虑...
  • 驱动(百度百科)

    2011-11-21 13:32:55
    驱动  一,什么驱动(出处《代码大全》,对软件感兴趣者,此书值得一看) ... 驱动,又称之为驱动法、驱动方法。...驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或
  • 6.2 goto 语句以及goto 语句构成循环 71 6.3 while语句 72 6.4 do-while语句 74 6.5 for 语句 76 6.6 循环的嵌套 79 56.7 几种循环的比较 79 6.8 break 和 continue语句 79 6.8.1 break 语句 79 6.8.2 continue ...
  • 驱动初步接触之Map代替if/switch

    千次阅读 2017-06-26 13:11:29
    驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来的方法。事实上,任何信息都可以通过来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,...
  • 6.2 goto 语句以及goto 语句构成循环 71 6.3 while语句 72 6.4 do-while语句 74 6.5 for 语句 76 6.6 循环的嵌套 79 56.7 几种循环的比较 79 6.8 break 和 continue语句 79 6.8.1 break 语句 79 6.8.2 continue ...
  • 函数指针的使用其实是很灵活的,它有很多技巧性很高的应用,在驱动方法中的应用很典型,这里着重介绍一下。...驱动方法是一种使你可以在查找信息,而不必很多的逻辑语句(if或Case)来把它们找出来
  • 可以做表拆分,减少单表字段数量,优化表结构。 在保证主键有效的情况下,检查主键索引的字段顺序,使得查询语句中条件的字段顺序和主键索引的字段顺序保持一致。 主要两种拆分 垂直拆分,水平拆分。 垂直分表 也就...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 304
精华内容 121
关键字:

查找表结构用什么语句