在oracle中,每个表都必须有一个列具有惟一性,比如rowid,在access中也要求每个表必须有一个惟一列,可是在sql server中为何就没有呢?
---------------------------------------
据说rowid是惟一的标志,是物理层次的,oracle查找时就是根据这个列的.可是为何sql server中可以充许所有列都可以重复呢?
从这一点上来说,好象连access都比sql server严谨些.
当然是我不理解才这样说的.可是我确实不解,为何sql server中就不要求每个表都必须有一个惟一性的列呢?(就象access那样,没有惟一的列,保存时它会自动增一个自增列.)
谢谢指教先.

解决方案 »

  1.   

    Please view Primary Key property in Books Online
      

  2.   

    Please view Primary Key property in Books Online
    -------------------
    谢谢,我知道是可以设主键的.
    可是我想问的是:
    在access或oracle中,如果一个表中没有主键,就必须有一个自增列才行.可是在sql server中,如果一个又没有主键,也没有自增列,也是可以保存的.
    这样就会存在这种情况,即多行完全相同.没有任何一个字段能标识这一行.
    可是这种情况在access中或oracle中是绝对不可能出现的.
    谢谢再.
      

  3.   

    It's not the problem of SQL Server and just a problem of yourself
      

  4.   

    It's not the problem of SQL Server and just a problem of yourself
    --------------------
    呵呵,谢谢,我知道这只是我的问题,我就是不会才问的呀,我不是学sql server不好,这是世界三大数据库之一,只是我不明白其中的道理,为何有这种不同呢?
    讲讲道理吧.老大.
      

  5.   

    就象access那样,没有惟一的列,保存时它会自动增一个自增列
    ---------------------------------------------In Access,the identity column is not indispensable too,You can also save the structure of table without it.
      

  6.   

    谢谢,试了下,确实在access中,也可以每条记录完全相同呀?
    是我理解错了。
    可是我不解,象存在多条记录完全相同的情况下,如何发送一条语句对其中一条进行更新呀。
    好象这种情况只能全部更新,而无法用语句只更新其中一条吧。
      

  7.   

    可是我不解,象存在多条记录完全相同的情况下,如何发送一条语句对其中一条进行更新呀。
    好象这种情况只能全部更新,而无法用语句只更新其中一条吧。
    ------------------
    不是的,可以单条更新!
    Set RowCount 1
    Update A
    Set ...
    From ...
    Set RowCount 0
      

  8.   

    可是我不解,象存在多条记录完全相同的情况下,如何发送一条语句对其中一条进行更新呀。
    好象这种情况只能全部更新,而无法用语句只更新其中一条吧。
    ------------------------------------
    Just like what you saidIt can't be distinguish from each for DATA BASE SOFT in this situation
      

  9.   

    Sorry for made a miss...But I think it has no sense here.Because you can't confirm which one you really want to update is updated or not
      

  10.   

    在SQLSERVER中,如果存在多条记录完全相同的情况下,除非发送更新语句(当然这条更新语句会同时更新这些完全相同的行),否则在企业管理器或客户端应用程序的表格中进行更新时会导致无法为更新定位行错误,SQLSERVER不知道要更新哪一行,因为行不是唯一的.
    解决的办法通常是为表增加IDENTITY自动增量标识列,每插入一行就由系统生成一个新的ID.IDENTITY列的特点是不能修改已生成的值,但可以将SET IDENTITY_INSERT 设置为ON后由用户为该列插入指定值,这种情况下就存在IDENTITY列值重复的可能,所以通常将该列设置UNIQUE约束(也可以设置为主键,但本人倾向于设置UNIQUE约束),防止该列的值重复,以唯一标识每一行.
    另外,SQLSERVER还提供了另外一种唯一标识每一行的方法,就是将某个列的数据类型设置为uniqueidentifier,并且将其默认值设为newid(),这样,每插入一行,系统就为该行生成一个全球唯一标识符,以保证行唯一,这种保证行唯一的方式通常应用于复制中.
    当使用ADO以行缓冲模式添加新记录时,如果表有IDENTITY列,则默认状态下ADO会为新行的IDENTITY列返回SQLSERVER的@@IDENTITY全局变量值,然后依据该值来刷新ADO新添加记录的列(如显示默认值),类似于这样一个过程:
    oRecordSet2.open(select * from table where id = @@identity)
    oRecordSet1.Fields(0).value = oRecordSet2.Fields(0).value
    ......
    而且,使用ADO新添加的记录若要刷新,只能通过IDENTITY列,而不能通过其它列,例如uniqueidentifier列,因为新行中只有IDENTITY列能够返回值(@@IDENTITY全局变量值),其它列都是空值.
    但是,因为@@IDENTITY返回的是最后插入表的IDENTITY列值,所以,当插入新行的表有INSERT触发器,并且INSERT触发器中向另一个含有IDENTITY列的表(假设为B表)中插入新行时,@@IDENTITY中返回的将是B表新插入行的ID值,这会导致大麻烦.可以在企业管理器中来测试一下:
    1.首先在查询分析器中创建ta,tb二个表,ta表中的INSERT触发器中向tb表插入新行.
    if object_id('ta') is not null
    drop table ta
    if object_id('tb') is not null
    drop table tb
    ----创建测试表
    create table ta(id int identity,num int,guid uniqueidentifier default newid())
    create table tb(id int identity,num int)
    ----为b表插入3行,id自动生成,分别1,2,3
    insert into tb default values
    insert into tb default values
    insert into tb default values
    select * from tb
    go
    ----为a表创建INSERT触发器,每向ta表插入一行,就同时向tb表也插入一行
    create trigger tri_insert_test on ta
    for insert
    as
    insert into tb default values
    go
    2.在企业管理器中打开ta表,向第一行的num中随便输入个整数,再向下移动光标,会发现第一行的id变为4而不是1(另外请注意,只有id列返回值,其它列均为NULL,即使设置了默认值).数值4正是tb的新行的id值!这时,在查询分析器中执行一下select * from ta,发现第一行的id为1而不是4.
    接着继续测试:
    在企业管理器中修改第一行的num,再将光标移出第一行,会导致错误"无法为更新定位行"错误(可按ESC取消修改),因为在ta表中没有找到id=4的行.
    所以,为含有IDENTITY列的表设置INSERT触发器时一定要注意这一点.