一个表USER,就一个列ID,里面有1,2,3三行,ID是主键就是按升序排的DECLARE @i INT
SET ROWCOUNT 1
SELECT @i=id FROM dbo.Users
PRINT @i这样输出的竟然是2DECLARE @i INT
SET ROWCOUNT 1
SELECT @i=id FROM dbo.Users ORDER BY id asc
PRINT @i这样输出就是1然后不写SET ROWCOUNTDECLARE @i INT
SELECT @i=id FROM dbo.Users ORDER BY id
PRINT @i这样输出是3,就是把最后一个值赋予@i了然后不写orderDECLARE @i INT
SELECT @i=id FROM dbo.Users
PRINT @i
输出变成1了。谁能解释上述4种情况的原理,我找不出原因,非常感谢

解决方案 »

  1.   

    估计没有聚集索引,所以返回的顺序是不一样的,你的第一个查询我测试是1CREATE TABLE [USER] (id INT IDENTITY(1,1))
     SET IDENTITY_INSERT [USER] ON 
     INSERT INTO [user](id)
     SELECT 1
     UNION 
     SELECT 2
     UNION 
     SELECT 3
     SET IDENTITY_INSERT [USER] OFF 
     DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM [User]
     PRINT @i
     /*
     1
     
     */
      

  2.   

    1.你的表是应该是堆表。所以不指定排序是不保证顺序的。
    2.你ROWCOUNT 1 指定 ID ASC 后当然返回是1
    3。你指定排序并赋值给变量@I 那么最后一次的值显示是3 当然输出是3
    4.跟你1同理由.
      

  3.   

    原因就是你的Users表没有聚集索引,并且数据的插入顺序是 2 3 1
    注意 set ROWCOUNT 是会话级别的,不断开会话设置回一直存在
      

  4.   

    就是这样的啊,ID是主键,难道是因为这个qqopenid上有个非聚集索引的关系吗,可是默认不是按聚集索引排的吗,太奇怪了
      

  5.   

    大侠,您帮我看看我这表,怎么就有这问题了
    USE [ZyDb]
    GO
    /****** 对象:  Table [dbo].[Users]    脚本日期: 10/16/2012 21:26:06 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[Users](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [qqOpenID] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [userName] [nvarchar](30) COLLATE Chinese_PRC_CI_AS NOT NULL CONSTRAINT [DF_Users_userName]  DEFAULT ('猪猪会员'),
    [wbName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
    [qqImg] [varchar](600) COLLATE Chinese_PRC_CI_AS NOT NULL,
    [experience] [int] NOT NULL CONSTRAINT [DF_Users_experience]  DEFAULT ((0)),
    [wealth] [int] NOT NULL CONSTRAINT [DF_Users_wealth]  DEFAULT ((0)),
    [balance] [int] NOT NULL CONSTRAINT [DF_Users_balance]  DEFAULT ((0)),
    [rankType] [tinyint] NOT NULL CONSTRAINT [DF_Users_rankType]  DEFAULT ((0)),
    [sex] [bit] NOT NULL CONSTRAINT [DF_Users_sex]  DEFAULT ((1)),
    [introduction] [nvarchar](500) COLLATE Chinese_PRC_CI_AS NULL,
    [isAllow] [bit] NOT NULL CONSTRAINT [DF_Users_isAllow]  DEFAULT ((1)),
    [guidKey] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Users_guidKey]  DEFAULT (newid()),
    [typeid] [smallint] NOT NULL,
    [fire] [int] NOT NULL CONSTRAINT [DF_Users_fire]  DEFAULT ((0)),
    [up] [int] NOT NULL CONSTRAINT [DF_Users_up]  DEFAULT ((0)),
    [inTime] [datetime] NOT NULL CONSTRAINT [DF_Users_inTime]  DEFAULT (getdate()),
     CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED 
    (
    [ID] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]GO
    SET ANSI_PADDING OFF
    GO
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID GUID' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users', @level2type=N'COLUMN', @level2name=N'ID'GO
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'1主网站2是360PC平台' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users', @level2type=N'COLUMN', @level2name=N'typeid'GO
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users'GO
    USE [ZyDb]
    GO
    ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [CK_Users] CHECK  ((charindex('&',[userName])=(0)))
    GO
    ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [CK_Users_1] CHECK  ((charindex('&',[introduction])=(0)))
      

  6.   

    我TRUNCATE TABLE dbo.Users 又插入了2条数据,还是这个问题,晕死
      

  7.   

    我用你的脚本创建,然后把其他列注释掉,用你1楼的语句来执行,全部都是1,如果非要说有问题,恐怕是其他列导致的
    SET ANSI_NULLS ON
     GO
     SET QUOTED_IDENTIFIER ON
     GO
     SET ANSI_PADDING ON
     GO  
     CREATE TABLE [dbo].[Users](
         [ID] [int] IDENTITY(1,1) NOT NULL--,
         --[qqOpenID] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
         --[userName] [nvarchar](30) COLLATE Chinese_PRC_CI_AS NOT NULL CONSTRAINT [DF_Users_userName]  DEFAULT ('猪猪会员'),
         --[wbName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
         --[qqImg] [varchar](600) COLLATE Chinese_PRC_CI_AS NOT NULL,
         --[experience] [int] NOT NULL CONSTRAINT [DF_Users_experience]  DEFAULT ((0)),
         --[wealth] [int] NOT NULL CONSTRAINT [DF_Users_wealth]  DEFAULT ((0)),
         --[balance] [int] NOT NULL CONSTRAINT [DF_Users_balance]  DEFAULT ((0)),
         --[rankType] [tinyint] NOT NULL CONSTRAINT [DF_Users_rankType]  DEFAULT ((0)),
         --[sex] [bit] NOT NULL CONSTRAINT [DF_Users_sex]  DEFAULT ((1)),
         --[introduction] [nvarchar](500) COLLATE Chinese_PRC_CI_AS NULL,
         --[isAllow] [bit] NOT NULL CONSTRAINT [DF_Users_isAllow]  DEFAULT ((1)),
         --[guidKey] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Users_guidKey]  DEFAULT (newid()),
         --[typeid] [smallint] NOT NULL,
         --[fire] [int] NOT NULL CONSTRAINT [DF_Users_fire]  DEFAULT ((0)),
         --[up] [int] NOT NULL CONSTRAINT [DF_Users_up]  DEFAULT ((0)),
         --[inTime] [datetime] NOT NULL CONSTRAINT [DF_Users_inTime]  DEFAULT (getdate()),
      CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED 
     (
         [ID] ASC
     )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
     ) ON [PRIMARY]
     
     --GO
     --SET ANSI_PADDING OFF
     --GO
     --EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'ID GUID' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users', @level2type=N'COLUMN', @level2name=N'ID'
     
     --GO
     --EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'1主网站2是360PC平台' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users', @level2type=N'COLUMN', @level2name=N'typeid'
     
     --GO
     --EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'Users'
     
     --GO
     --USE [ZyDb]
     --GO
     --ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [CK_Users] CHECK  ((charindex('&',[userName])=(0)))
     --GO
     --ALTER TABLE [dbo].[Users]  WITH CHECK ADD  CONSTRAINT [CK_Users_1] CHECK  ((charindex('&',[introduction])=(0)))
     
     
     SELECT * FROM [users]
     
     DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM dbo.Users
     PRINT @i
     go
     DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM dbo.Users ORDER BY id asc
     PRINT @i
     go
     DECLARE @i INT
     SELECT @i=id FROM dbo.Users ORDER BY id
     PRINT @i
     go
     DECLARE @i INT
     SELECT @i=id FROM dbo.Users
     PRINT @i
      

  8.   

    真奇怪了,我TRUNCATE TABLE dbo.Users ,然后写个insert的语句插入2条,然后一切正常。是1,但是我通过程序插入这个表,也是1,2两条,结果就变成2了。这怎么回事啊,这问题大了,1000分求救
      

  9.   

    你有没有检查过程序的插入语句?用Profiler来监控一下,你的列比较多,造数据有点麻烦
      

  10.   

    我把添加的存储过程贴出来,帮我看看好不,什么原因,噩梦啊ALTER PROC [dbo].[addUser]
    (
    @qqOpenID VARCHAR(50),
    @userName NVARCHAR(30),
    @qqImg VARCHAR(600),
    @rankType TINYINT,
    @sex TINYINT,
    @guidKey CHAR(36) OUT,
    @wbName VARCHAR(50),
    @id INT OUT,
    @introduction NVARCHAR(500),
    @typeid SMALLINT
    )
    AS
        DECLARE @oldWb VARCHAR(50)
        DECLARE @oldqqImg VARCHAR(600)
    SELECT @id=ID,@guidKey=guidKey,@oldWb=wbName,@oldqqImg=qqImg FROM Users WHERE qqOpenID=@qqOpenID
    IF(@@ROWCOUNT>0)
    BEGIN
    IF(@oldWb IS NULL AND @wbName<>'')
    UPDATE Users SET wbName=@wbName WHERE ID=@id
    IF(@oldqqImg<>@qqImg)
    BEGIN
    set xact_abort ON
    BEGIN TRAN
    UPDATE Users SET qqImg=@qqImg WHERE ID=@id
    DECLARE @qqImg100 VARCHAR(200)
    SET @qqImg100=dbo.img(@qqImg,100)
    UPDATE room SET qqImg=@qqImg100 WHERE id=@id
    COMMIT TRAN
    END
    RETURN 65;
    END
    ELSE
    BEGIN
    INSERT Users(qqOpenID,userName,qqImg,rankType,sex,wbName,typeid,introduction) VALUES(@qqOpenID,@userName,@qqImg,@rankType,@sex,@wbName,@typeid,@introduction)
    SELECT @id=ID,@guidKey=guidKey FROM Users WHERE qqOpenID=@qqOpenID
    RETURN 66;
    END
      

  11.   

    大哥,在吗,奇怪了,那个qqopenid我插入1,2那没问题,结果是1.我第一个插DA58CA3A8BF9015CBAC9A8A05FB92DF5第二个插
    2FD75BB32F31655810C2AA0C5C1E8F30结果就是2了,简直无语了,超自然现象
      

  12.   

    你单单查询userid不应该会收到其他列的影响啊。难道你的SQLServer有做什么配置?你记得有没有改过什么?是不是安装后就没改动过?
      

  13.   

    USE [kk]
    GO
    /****** 对象:  Table [dbo].[Users]    脚本日期: 10/16/2012 22:31:18 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    CREATE TABLE [dbo].[Users](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [openid] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
     CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
    (
    [id] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]GO
    SET ANSI_PADDING OFF先建立这个表然后运行
    INSERT users(OpenID) VALUES('DA58CA3A8BF9015CBAC9A8A05FB92DF5')
    INSERT users(OpenID) VALUES('2FD75BB32F31655810C2AA0C5C1E8F30')DECLARE @i INT
    SET ROWCOUNT 1
    SELECT @i=id FROM dbo.Users
    PRINT @i输出为2然后TRUNCATE TABLE dbo.UsersINSERT users(OpenID) VALUES('1')
    INSERT users(OpenID) VALUES('2')输出为1
      

  14.   

    经验证,你的SQLServer有问题,我执行了,都是1
    SET ANSI_NULLS ON
     GO
     SET QUOTED_IDENTIFIER ON
     GO
     SET ANSI_PADDING ON
     GO
     CREATE TABLE [dbo].[Users](
         [id] [int] IDENTITY(1,1) NOT NULL,
         [openid] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
      CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
     (
         [id] ASC
     )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
     ) ON [PRIMARY]
     
     GO 
     SET ANSI_PADDING OFF
     
     
     INSERT users(OpenID) VALUES('DA58CA3A8BF9015CBAC9A8A05FB92DF5')
     INSERT users(OpenID) VALUES('2FD75BB32F31655810C2AA0C5C1E8F30')
     
     DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM dbo.Users
     PRINT @i
     
     --输出为2
     
     --然后
     TRUNCATE TABLE dbo.Users
     
     INSERT users(OpenID) VALUES('1')
     INSERT users(OpenID) VALUES('2')
     
     
     DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM dbo.Users
     PRINT @i
     
     --输出为1
      

  15.   

    不是啊,你这个openid上没索引,很奇怪导出表怎么没这个,您按我这个设置我都慌了
      

  16.   

    嗯,您创建好后,再这样在openid上创建一个非聚集索引,您一般创建非聚集索引是这样操作的吗
      

  17.   

    创建好那个非聚集索引后,
    INSERT users(OpenID) VALUES('DA58CA3A8BF9015CBAC9A8A05FB92DF5')
    INSERT users(OpenID) VALUES('2FD75BB32F31655810C2AA0C5C1E8F30')DECLARE @i INT
     SET ROWCOUNT 1
     SELECT @i=id FROM dbo.Users
     PRINT @i显示就是2了
      

  18.   


    2条数据啊INSERT users(OpenID) VALUES('DA58CA3A8BF9015CBAC9A8A05FB92DF5')
    INSERT users(OpenID) VALUES('2FD75BB32F31655810C2AA0C5C1E8F30')
      

  19.   

    INSERT users(OpenID) VALUES('DA58CA3A8BF9015CBAC9A8A05FB92DF5')
     INSERT users(OpenID) VALUES('2FD75BB32F31655810C2AA0C5C1E8F30')
    select * from users
    你这样执行,怎么痒都是第二条,而且只有第二条,我在看你是不是哪里做了设置,的确很奇怪
      

  20.   

    实际上不用纠结这个问题,你这个写法并得不到T-SQL标准的支持,要按顺序使用数据集,
    就要加order by ,想偷这个懒,会付出惨痛的代价的,而且也不需要用 set rowcount吧,你想取第一个,用top就好了
      

  21.   


    这个是 SET ROWCOUNT 0 的关系,之前设了SET ROWCOUNT 1 ,他缓存了,您执行下SET ROWCOUNT 0就好了,您是不是2呢?
      

  22.   

    问题是我就算select * from users,在插入了两条语句后,结果只有一条,而且是第二条,所以她的查询怎么都是2
      

  23.   


    你那个前面SET ROWCOUNT 1 执行到了,缓存了,你执行下SET ROWCOUNT 0,再select * from users 就2条了
      

  24.   

    我估计是你的数据有问题。DA58CA3A8BF9015CBAC9A8A05FB92DF5这个是什么类型的?原来传进来的时候
      

  25.   


    string类型,是腾讯QQ登录的OPEDNID,这个没问题的吧,大侠我想问个东西,那个非聚集索引的ASC升序降序是什么意思,不是都按照主键升序降序排的吗。
      

  26.   

    这事什么情况,ID怎么降序排了,我这个ID聚集索引明明是asc的
      

  27.   

    我找到问题了,还是单独索引排序的问题1、先把表上所有主键、聚集索引、非聚集索引删除
    2、CREATE CLUSTERED INDEX Clustered_user ON users (id,openid ASC )
    3、把id设回主键然后你插入数据,就得到你想要的了
      

  28.   

    看看你数据库的排序规则?SELECT name, collation_name FROM sys.databases 
    /*name                                                                                                                             collation_name
    -------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------
    master                                                                                                                           Chinese_PRC_CI_AS
    tempdb                                                                                                                           Chinese_PRC_CI_AS
    model                                                                                                                            Chinese_PRC_CI_AS
    msdb                                                                                                                             Chinese_PRC_CI_AS
    ReportServer                                                                                                                     Latin1_General_CI_AS_KS_WS
    ReportServerTempDB                                                                                                               Latin1_General_CI_AS_KS_WS
    SQLTool                                                                                                                          Chinese_PRC_CI_AS
    TestDB                                                                                                                           Chinese_PRC_CI_AS*/
      

  29.   

    噢?这样?你还设了普通索引?
    打开执行几乎看看知不是进行了索引扫描,根本没有访问聚集索引
    如果是这样的话就是按照索引的排序顺序来的
    因为你没有ORDER BY ,数据库并不帮你维护这个顺序,所以这也是有可能的
      

  30.   

    您的意思是如果一个表里有聚集索引和非聚集索引,查的时候最好加上ORDER BY是吗?
      

  31.   

    无论有没有,加上order by都是好的
      

  32.   


    您刚才这样CREATE CLUSTERED INDEX Clustered_user ON users (id,openid ASC )
    就不是2了吗,就是1了吗,那怎么解释呢,这样就用到聚集索引了吗,您这样不会是多列主键吧,根本不是非聚集索引
      

  33.   

    不是查询要加order by 加order by 需要额外的开销,如果你不需要数据排序,最好不要加,
    因为你希望数据按你想的方式排序,所以就要加
      

  34.   

    主键和聚集索引是两回事,只是SQLServer默认这种行为而已。我这是强制按照第一列来排序,如果第一列相同,按第二列来排序
      

  35.   

    哦,最后一个问题,为啥非聚集索引很少会单列做索引呢,我这个OPENID要求快速定位,且是唯一的,是否应该在这个列上做个非聚集索引呢?
      

  36.   


    嗯,我就是这样建的,而且我测试了大数据比如select * from user where openid='asxasxasx'这样,是走到那个非聚集索引的,就是起作用了是吧
      

  37.   

    order by、top n才是精确的做法,它是有保证的
    否则,只能取决于数据库自己的不同实现而不同了,它是不保证的
      

  38.   

    fdsdfsfsd