2013-07-19 3 views
2

Следующий запрос возвращает два различных результатов в двух экземплярах SQL Server 2008 R2:Различные поведение вложенного запроса на 2 различных SQL Server 2008 R2

create table a(id int) 

insert into a(id) 
values(1) 

insert into a(id) 
values(2) 

select 
    id, 
    (select count(dbo.a.id) from dbo.a where dbo.a.id = "a"."id") 
from a 
where a.id = 1 

Первая машина дает

id   
----------- ----------- 
1   2 

Во-вторых машина дает

id   
----------- ----------- 
1   1 

Мы знаем, как исправить эту проблему, используя явный псевдоним в подвале чень. Но поскольку мы так много используем конструкции, это было бы огромной работой. Поэтому мы хотели бы понять проблему.

Возможно, есть опция в SQL Server для управления этим поведением?

2013/07/22:

DBCC USEROPTIONS; SELECT @@ VERSION; дает

Set Option     Value 
----------------------------- ---------------- 
textsize      2147483647 
language      Deutsch 
dateformat     dmy 
datefirst      1 
lock_timeout     -1 
quoted_identifier    SET 
arithabort     SET 
ansi_null_dflt_on    SET 
ansi_warnings     SET 
ansi_padding     SET 
ansi_nulls     SET 
concat_null_yields_null  SET 
isolation level    read committed 
------------------------------------ 
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86) 
     Jun 17 2011 00:57:23 
     Copyright (c) Microsoft Corporation 

     Enterprise Edition on Windows NT 6.0 <X86> (Build 6002: Service Pack 2) 

и

Set Option     Value 
----------------------------- ---------------- 
textsize      2147483647 
language      Deutsch 
dateformat     dmy 
datefirst      1 
lock_timeout     -1 
quoted_identifier    SET 
arithabort     SET 
ansi_null_dflt_on    SET 
ansi_warnings     SET 
ansi_padding     SET 
ansi_nulls     SET 
concat_null_yields_null  SET 
isolation level    read committed 
------------------------------------ 
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) 
     Apr 2 2010 15:48:46 
     Copyright (c) Microsoft Corporation 
     Standard Edition (64-bit) on Windows NT 5.2 <X64> (Build 3790: Service Pack 2) 

Для первого сервера работу запроса, как мы этого хотим.

2013/07/24

Это, кажется, не зависит от сервера, но в базах данных.

Сервер:

Set Option     Value 
---------------------------- ---------------------------------------------- 
textsize      2147483647 
language      Deutsch 
dateformat     dmy 
datefirst     1 
lock_timeout     -1 
quoted_identifier   SET 
arithabort     SET 
ansi_null_dflt_on   SET 
ansi_warnings    SET 
ansi_padding     SET 
ansi_nulls     SET 
concat_null_yields_null  SET 
isolation level    read committed 

(13 Zeile(n) betroffen) 

Die DBCC-Ausführung wurde abgeschlossen. Falls DBCC Fehlermeldungen ausgegeben hat, wenden Sie sich an den Systemadministrator. 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (Intel X86) 
Jun 17 2011 00:57:23 
Copyright (c) Microsoft Corporation 
Enterprise Edition on Windows NT 6.0 <X86> (Build 6002: Service Pack 2) 


(1 Zeile(n) betroffen) 

После запроса:

create table a(id int) 
insert into a(id) 
values(1) 
insert into a(id) 
values(2) 
select * from a 
select 
    id, 
    (select count(dbo.a.id) from dbo.a where dbo.a.id = "a"."id") 
from a 
where a.id = 1 
drop table a 
SELECT USER_NAME() AS CurrentUser; 
SELECT SCHEMA_NAME() AS CurrentSchema; 

Первая база данных дает:

id 
----------- 
1 
2 

(2 Zeile(n) betroffen) 

id   
----------- ----------- 
1   2 

(1 Zeile(n) betroffen) 

CurrentUser 
-------------------------- 
dbo 

(1 Zeile(n) betroffen) 

CurrentSchema 
-------------------------- 
dbo 

(1 Zeile(n) betroffen) 

Вторая база данных дает:

id 
----------- 
1 
2 

(2 Zeile(n) betroffen) 

id   
----------- ----------- 
1   1 

(1 Zeile(n) betroffen) 

CurrentUser 
----------------------- 
dbo 

(1 Zeile(n) betroffen) 

CurrentSchema 
----------------------- 
dbo 

(1 Zeile(n) betroffen) 
+0

Run 'DBCC USEROPTIONS; SELECT @@ VERSION,' на обоих случаях и опубликовать результаты. –

+1

Результаты добавлены ... – user2598804

+0

Это (ссылка) (http://support.microsoft.com/kb/298674/en-us)) является ожидаемым поведением в таких случаях (подзапросы). Попробуйте запустить этот запрос 'SELECT * FROM sys.databases d WHERE d.database_id = DB_ID()' в обеих базах данных и сравнить результаты. Скажите, пожалуйста, если вы что-то найдете. –

ответ

0

Простейшим объяснением может быть то, что эти таблицы a имеют разницу. строк.

В противном случае я не могу воспроизвести проблему. Запрос, который ссылается на объекты без явной схемы (например, SELECT * FROM A), может дать вам diff. результаты на том же сервере если

1) Этот запрос выполняется diff. пользователи.

2) Пользователи сопоставлены с разницей. схемы (например, dbo и dbo2).

3) В diff есть две (или более) таблицы/объекты с одинаковым именем. схемы (например: dbo.A и dbo2.A).

Выполнить этот скрипт в SSMS с SQLCMD mode выбран (меню: Запрос> Режим SQLCMD):

SET NOCOUNT ON; 
CREATE DATABASE Test; 
GO 
USE Test; 
GO 

CREATE TABLE dbo.A(ID INT); 
INSERT INTO dbo.A(ID) VALUES (1); 
GO 

CREATE SCHEMA dbo2; 
GO 
CREATE TABLE dbo2.A(ID INT); 
INSERT INTO dbo2.A(ID) VALUES (1),(2); 
GO 
-- Test database has two tables [A] with diff. schema (dbo, dbo2) 

USE master; 
GO 
CREATE LOGIN login_test_1 WITH PASSWORD='pas$w0Rd', DEFAULT_DATABASE=Test; 
GO 
CREATE LOGIN login_test_2 WITH PASSWORD='pas$w0Rd', DEFAULT_DATABASE=Test; 
GO 
USE Test; 
GO 
-- This user is mapped to schema [dbo] 
CREATE USER user_test_1 FOR LOGIN login_test_1 WITH DEFAULT_SCHEMA=dbo; 
GO 
GRANT SELECT ON dbo.A TO user_test_1; 
GO 
GRANT SELECT ON dbo2.A TO user_test_1; 
GO 
-- This user is mapped to schema [dbo2] (!) 
CREATE USER user_test_2 FOR LOGIN login_test_2 WITH DEFAULT_SCHEMA=dbo2; 
GO 
GRANT SELECT ON dbo.A TO user_test_2; 
GO 
GRANT SELECT ON dbo2.A TO user_test_2; 
GO 

-- Test login_test_1 
:CONNECT (local)\SQL2008R2 -U login_test_1 -P pas$w0Rd 
SELECT USER_NAME() AS CurrentUser; 
SELECT SCHEMA_NAME() AS CurrentSchema; 
SELECT * 
FROM A; 
GO 

-- Test login_test_2 
:CONNECT (local)\SQL2008R2 -U login_test_2 -P pas$w0Rd 
SELECT USER_NAME() AS CurrentUser; 
SELECT SCHEMA_NAME() AS CurrentSchema; 
SELECT * 
FROM A; 
GO 
SET NOCOUNT OFF; 

Результаты:

Connecting to (local)\SQL2008R2 as login_test_1... 
CurrentUser 
-------------------------------------------------------------------------------------------------------------------------------- 
user_test_1 
CurrentSchema 
-------------------------------------------------------------------------------------------------------------------------------- 
dbo 
ID 
----------- 
1 
Disconnecting connection from (local)\SQL2008R2 as login_test_1... 

Connecting to (local)\SQL2008R2 as login_test_2... 
CurrentUser 
-------------------------------------------------------------------------------------------------------------------------------- 
user_test_2 
CurrentSchema 
-------------------------------------------------------------------------------------------------------------------------------- 
dbo2 
ID 
----------- 
1 
2 
Disconnecting connection from (local)\SQL2008R2 as login_test_2... 

В этом случае login_test_1 (DBO) получает строку но login_test_2 (dbo2) получает строк.

Cleanup сценарий:

/* 
DROP DATABASE Test; 
DROP LOGIN login_test_1; 
DROP LOGIN login_test_2; 
GO 
*/ 
+1

некоторые детали добавлены – user2598804