Böylece CAST
uzaktaki durumda değil, yerel olarak yapıldığını fark ettikten sonra hatayı tekrar oluşturabildim . Daha önce bunu düzeltmek umuduyla SP3'e geçmeyi tavsiye ettim (kısmen SP3'teki hatayı tekrar oluşturamadığımdan ve kısmen de olsa iyi bir fikir olduğu için). Ancak, şimdi hatayı yeniden oluşturabildiğim için SP3'e geçmenin hala iyi bir fikir olsa da bunu düzeltmeyeceği açık. Ayrıca, SQL Server 2008 R2 RTM ve 2014 SP1'deki hatayı (her üç vakada da bir "geridönüşüm" yerel Bağlantılı Sunucu kullanarak) yeniden ürettim.
Sorun ile ilgisi var gibi görünüyor nerede sorgu yürütülürken, ya da en azından nerede kısmı (lar) o yürütme edilir. Bunu CAST
, çalışmanın çalışmasını sağladığım için söylüyorum , ancak yalnızca yerel bir DB nesnesine bir başvuru ekleyerek:
SELECT rmt.*, CAST(NULL AS UNIQUEIDENTIFIER) AS [GUID]
FROM [Local].[database_name].[dbo].[table_name] rmt
CROSS JOIN (SELECT TOP (1) 1 FROM [sys].[data_spaces]) tmp(dummy);
Bu gerçekten işe yarıyor. Ancak aşağıdaki orijinal hata alır:
SELECT rmt.*, CAST(NULL AS UNIQUEIDENTIFIER) AS [GUID]
FROM [Local].[database_name].[dbo].[table_name] rmt
CROSS JOIN (VALUES (1)) tmp(dummy);
Yerel referanslar olmadığında, tüm sorgunun yürütülecek uzak sisteme gönderildiğini ve bazı nedenlerden dolayı OLE DB sürücüsü tarafından yanlış çevrildiğini veya belki de yanlış çevrildiğini NULL
tahmin ediyorum.UNIQUEIDENTIFIER
NULL
Yaptığım sınamaya göre, bu bir hata gibi görünüyor, ancak hatanın SQL Server veya SQL Server Native Client / OLEDB sürücüsü içinde olup olmadığından emin değilim. Bununla birlikte, dönüşüm hata OLEDB sürücüsünden oluşur ve bu nedenle mutlaka dönüştürme bir sorun değildir INT
için UNIQUEIDENTIFIER
sürücü yana (SQL Server izin verilmeyen bir dönüşüm) dönüşümleri (SQL Server da değil yapılacak SQL Server kullanmıyor dönüştürme INT
için izin DATE
, ancak henüz OLEDB sürücüsü, testlerden birinde gösterildiği gibi başarılı bir şekilde işler.
Üç test yaptım. Başarılı olan ikisi için, uzaktan yürütülen sorguyu gösteren XML çalıştırma planlarına baktım. Üçü için de, SQL Profiler ile herhangi bir İstisna ya da OLEDB olayını yakaladım:
Olaylar:
- Hatalar ve Uyarılar
- Dikkat
- İstisna
- Uygulama Uyarıları
- Kullanıcı Hata Mesajı
- OLEDB
- TSQL
- dışındakilerin tümü :
- SQL: StmtRecompile
- XQuery Statik Türü
Sütun Filtreleri:
- Uygulama Adı
- % GİBİ DEĞİL % Intellisense%
- SPID
Testler
Test 1
CAST(NULL AS UNIQUEIDENTIFIER)
bu çalışır
SELECT TOP (2) CAST(NULL AS UNIQUEIDENTIFIER) AS [Something]
, (SELECT COUNT(*) FROM sys.[data_spaces]) AS [lcl]
FROM [Local].[TEMPTEST].[sys].[objects] rmt;
XML yürütme planının ilgili kısmı:
<DefinedValue>
<ColumnReference Column="Expr1002" />
<ScalarOperator ScalarString="NULL">
<Const ConstValue="NULL" />
</ScalarOperator>
</DefinedValue>
...
<RemoteQuery RemoteSource="Local" RemoteQuery=
"SELECT 1 FROM "TEMPTEST"."sys"."objects" "Tbl1001""
/>
Test 2
CAST(NULL AS UNIQUEIDENTIFIER)
bu başarısız
SELECT TOP (2) CAST(NULL AS UNIQUEIDENTIFIER) AS [Something]
-- , (SELECT COUNT(*) FROM sys.[data_spaces]) AS [lcl]
FROM [Local].[TEMPTEST].[sys].[objects] rmt;
(not: Alt soruyu orada tuttum, yorum yaptım, böylece XML izleme dosyalarını karşılaştırdığımda daha az fark olacaktı)
Test 3
CAST(NULL AS DATE)
bu çalışır
SELECT TOP (2) CAST(NULL AS DATE) AS [Something]
-- , (SELECT COUNT(*) FROM sys.[data_spaces]) AS [lcl]
FROM [Local].[TEMPTEST].[sys].[objects] rmt;
(not: Alt soruyu orada tuttum, yorum yaptım, böylece XML izleme dosyalarını karşılaştırdığımda daha az fark olacaktı)
XML yürütme planının ilgili kısmı:
<DefinedValue>
<ColumnReference Column="Expr1002" />
<ScalarOperator ScalarString="[Expr1002]">
<Identifier>
<ColumnReference Column="Expr1002" />
</Identifier>
</ScalarOperator>
</DefinedValue>
...
<RemoteQuery RemoteSource="Local" RemoteQuery=
"SELECT TOP (2) NULL "Expr1002" FROM "TEMPTEST"."sys"."objects" "Tbl1001""
/>
Test # 3'e bakarsanız SELECT TOP (2) NULL
, "uzak" bir sistemde yapıyor. SQL Profiler izlemesi, bu uzak alanın veri tipinin gerçekte olduğunu gösterir INT
. İz ayrıca istemci tarafındaki alanın (yani sorguyu çalıştırdığım yer) DATE
beklendiği gibi olduğunu gösteriyor. Dönüşüm INT
için DATE
SQL Server bir hata alırsınız şey, OLEDB sürücüsü içinde sadece para cezası çalışır. Uzak değer NULL
, yani doğrudan döndürülür, dolayısıyla <ColumnReference Column="Expr1002" />
.
Test # 1'e bakarsanız SELECT 1
, "uzak" bir sistemde yapıyor. SQL Profiler izlemesi, bu uzak alanın veri tipinin gerçekte olduğunu gösterir INT
. İz ayrıca istemci tarafındaki alanın (yani sorguyu çalıştırdığım yer) GUID
beklendiği gibi olduğunu gösteriyor. Dönüşüm INT
için GUID
OLEDB sürücüsü içinde sadece para cezası çalışır, SQL Server bir hata alırsınız şey (bu sürücü içinde yapılır ve OLEDB "GUID" diyor, unutmayın). Uzak değer değildir NULL
, yani değişmez NULL
, yani <Const ConstValue="NULL" />
.
Test # 2 başarısız olur, bu nedenle yürütme planı yoktur. Ancak, "uzak" sistemi başarılı bir şekilde sorgular, ancak sonuç kümesini geri alamaz. SQL Profiler'in yakaladığı sorgu:
SELECT TOP (2) NULL "Expr1002" FROM "TEMPTEST"."sys"."objects" "Tbl1001"
Bu, Test # 1'de yapılan aynı sorgunun aynısı, ancak burada başarısız oluyor. Başka küçük farklılıklar da var ama OLEDB iletişimini tam olarak yorumlayamıyorum. Bununla birlikte, uzaktaki alan hala INT
(wType = 3 = adInteger / dört bayt işaretli tam sayı / DBTYPE_I4) iken "istemci" alanı hala GUID
(wType = 72 = adGUID / global benzersiz tanımlayıcı / DBTYPE_GUID) olarak gösteriliyor. OLE DB belgelerine kadar yardımcı olmuyor GUID Veri Türü Dönüşüm , DBDATE Veri Türü Dönüşümler ve I4 Veri Türü Dönüşümler dönüştürme göstermektedir I4 birine GUID veya DBDATE desteklenmeyen, henüz DATE
sorgu çalışır.
Üç sınama için İz XML dosyaları PasteBin'de bulunur. Her testin diğerlerinden farklı olduğu yerlerin ayrıntılarını görmek istiyorsanız, bunları yerel olarak kaydedebilir ve ardından üzerinde bir "fark" yapabilirsiniz. Dosyalar:
- NullGuidSuccess.xml
- NullGuidError.xml
- NullDateSuccess.xml
ERGO?
Bu konuda ne yapmalı? Muhtemelen sadece SQL Native Client - SQLNCLI11
- 'in SQL Server 2012 tarihinden itibaren kullanım dışı olduğu göz önüne alındığında, üst kısımda belirttiğim geçici çalışma . SQL Server Native Client konusundaki MSDN sayfalarının çoğu aşağıdaki bildirime sahiptir. üst:
Uyarı
SQL Server Native Client (SNAC), SQL Server 2012'nin ötesinde desteklenmemektedir. Yeni geliştirme çalışmalarında SNAC kullanmaktan kaçının ve şu anda kullanan uygulamaları değiştirmeyi planlayın. SQL Server için Microsoft ODBC sürücüsü , Microsoft SQL Server ve Microsoft Azure SQL Veritabanı Windows'dan ana bağlantı sağlar.
Daha fazla bilgi için lütfen bakınız:
ODBC mi?
ODBC Bağlantılı Sunucuyu şu şekilde kurarım:
EXEC master.dbo.sp_addlinkedserver
@server = N'LocalODBC',
@srvproduct=N'{my_server_name}',
@provider=N'MSDASQL',
@provstr=N'Driver={SQL Server};Server=(local);Trusted_Connection=Yes;';
EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname=N'LocalODBC',
@useself=N'True',
@locallogin=NULL,
@rmtuser=NULL,
@rmtpassword=NULL;
Ve sonra denedi:
SELECT CAST(NULL AS UNIQUEIDENTIFIER) AS [Something]
FROM [LocalODBC].[tempdb].[sys].[objects] rmt;
ve aşağıdaki hatayı aldı:
Bağlantılı sunucu için OLE DB sağlayıcısı "MSDASQL" "LocalODBC", "İstenen dönüşüm desteklenmiyor" iletisini döndürdü.
Msj 7341, Seviye 16, Durum 2, Satır 53
Bağlantılı sunucu "LocalODBC" için OLE DB sağlayıcısı "MSDASQL" 'den "(kullanıcı tarafından oluşturulan ifade) .Expr1002" sütununun geçerli satır değeri alınamıyor.
PS
GUID'lerin uzak ve yerel sunucular arasında taşınması ile ilgili olduğu için, NULL olmayan değerler özel bir sözdizimi üzerinden ele alınır. Çalıştığımda, SQL Profiler izlemesinde aşağıdaki OLE DB olay bilgisini fark ettim CAST(0x00 AS UNIQUEIDENTIFIER)
:
<RemoteQuery RemoteSource="Local" RemoteQuery=
"SELECT {guid'00000000-0000-0000-0000-000000000000'} "Expr1002" FROM "TEMPTEST"."sys"."objects" "Tbl1001""
/>
PPS
Ayrıca OPENQUERY
aşağıdaki sorguyla test ettim :
SELECT TOP (2) CAST(NULL AS UNIQUEIDENTIFIER) AS [Something]
--, (SELECT COUNT(*) FROM sys.[data_spaces]) AS [lcl]
FROM OPENQUERY([Local], N'SELECT 705 AS [dummy] FROM [TEMPTEST].[sys].[objects];') rmt;
ve yerel nesne referansı olmadan bile başarılı oldu. SQL Profiler izleme XML dosyası PasteBin'e şu adresten gönderildi:
NullGuidSuccessOPENQUERY.xml
XML yürütme planı, NULL
Test # 1 ile aynı olan bir sabit kullanarak gösteriyor .