'Çok parçalı tanımlayıcı' nedir ve neden bağlanamaz?


137

Tabloları başka bir tabloya göre güncellemeye çalıştığımda sürekli olarak bu hataları alıyorum. Sorguyu yeniden yazmayı bitiririm, birleşmelerin sırasını değiştiririm, bazı gruplamaları değiştiririm ve sonunda çalışır, ama tam olarak anlamıyorum.

'Çok parçalı tanımlayıcı' nedir?
'Çok parçalı tanımlayıcı' ne zaman bağlanamaz?
Zaten neye bağlı?
Hangi durumlarda bu hata meydana gelir?
Bunu önlemenin en iyi yolları nelerdir?

SQL Server 2005'teki belirli hata:

Çok parçalı tanımlayıcı "..." bağlanamadı.

İşte bir örnek:

UPDATE  [test].[dbo].[CompanyDetail]

SET Mnemonic = [dbBWKMigration].[dbo].[Company].[MNEMONIC], 
               [Company Code] = [dbBWKMigration].[dbo].[Company].[COMPANYCODE]

WHERE [Company Name] = **[dbBWKMigration].[dbo].[Company].[COMPANYNAME]**

Gerçek hata:

Msg 4104, Seviye 16, Durum 1, Satır 3 "dbBWKMigration.dbo.Company.COMPANYNAME" çok parçalı tanımlayıcısı bağlanamadı.

Yanıtlar:


101

Çok parçalı tanımlayıcı, birden fazla parça içeren bir alanın veya tablonun herhangi bir açıklamasıdır - örneğin MyTable.SomeRow - bağlı değilse, bununla ilgili yanlış bir şey olduğu anlamına gelir - ya basit bir yazım hatası ya da aralarında bir karışıklık var tablo ve sütun. Bunun nedeni, tablonuzda veya alan adlarınızda ayrılmış sözcüklerin kullanılması ve [] ile çevrilmemesi olabilir. Hedef tabloya gerekli tüm sütunların eklenmemesinden de kaynaklanabilir.

Redgate sql istemi gibi bir şey , bunları manuel olarak yazmak zorunda kalmaktan kaçınmak için mükemmeldir (yabancı anahtarlara dayalı birleşimleri otomatik olarak tamamlar), ancak ücretsiz değildir. SQL Server 2008, redgate sürümü kadar tam olmasa da, kutunun dışına çıkmayı destekler.


6
Hala gerçek: yazım ipucunuz günümü kurtardı.
Stefan

Yeni gelenler için gün koruyucu yorum: sadece yazım hatası kontrol edin, bazen küçük bir parça eksik olduğunda ortaya çıkar. Benim sorunumda, 50 + satır sorgu herhangi bir tırnak olmadan OBJECT_ID (Schema.Table) oldu.
Abdullah Ilgaz

57

Aslında bazen bir tabloyu başka bir tablonun verilerinden güncellerken, bu hataya neden olan yaygın sorunlardan birinin tablo kısaltmalarınızı yanlış kullandığınızda veya gerekli olmadığında olduğunu düşünüyorum . Doğru ifade aşağıdadır:

Update Table1
Set SomeField = t2.SomeFieldValue 
From Table1 t1 
Inner Join Table2 as t2
    On t1.ID = t2.ID

O Bildirimi SomeFieldsütun Tablo1 yok t1olarak eleme t1.SomeFieldama sadece olduğunu SomeField.

Biri t1.SomeField, ifadeyi belirterek güncellemeye çalışırsa , fark ettiğiniz çok parçalı hatayı döndürür.


3
Tablo takma adının önüne alan belirle Benim durumumda bu soruna neden olur.
Malhaar Punjabi

1
Benim sorunum da buydu. ABBREVIATION.My_FieldSadece ihtiyacım olduğunda SET vardı SET.My_Field;
VSO

Ben OPENJSON kullanırken bu hataya koştu. `Cust c OUTER UYGULAMA OPENJSON (cust.Addresses)` hatası attı. `Cust c OUTER UYGULAMA OPENJSON'undan (c.Adresler)` geri
sonuç kümesi

Sen dan açıklama bulabilirsiniz sqlservertutorial.net/sql-server-basics/sql-server-update-join yararlı:
CAtoOH

17

Muhtemelen bir yazım hatasıdır. Kodunuzda [şema] dediğiniz yerleri arayın. [TableName] (temel olarak bir alana başvurduğunuz herhangi bir yer) ve her şeyin doğru yazıldığından emin olun.

Şahsen, tüm tablolarım için takma ad kullanarak bundan kaçınmaya çalışıyorum. Uzun bir tablo adını açıklamasının kısaltmasına (yani WorkOrderParts -> WOP) kısaltabildiğinizde çok yardımcı olur ve ayrıca sorgunuzu daha okunabilir hale getirir.

Düzenleme: Ek bir bonus olarak, yazmanız gereken tek şey şema, tablo ve alan adları ile birlikte üç veya dört harfli bir takma ad olduğunda TONS tuş vuruşunu kaydedersiniz.


6

Bağlama = belirli bir sütunun metinsel temsili, bazı tablolarda, bazı veritabanlarında, bazı sunucularda fiziksel bir sütuna eşlenir.

Çok parçalı tanımlayıcı şunlar olabilir: MyDatabase.dbo.MyTable. Bu tanımlayıcılardan herhangi birini yanlış anlarsanız, eşlenemeyen çok parçalı bir tanımlayıcınız vardır.

Bundan kaçınmanın en iyi yolu, sorguyu ilk kez doğru yazmak veya intellisense sağlayan yönetim stüdyosu için bir eklenti kullanmak ve böylece yazım hatalarından kaçınarak size yardımcı olmaktır.


5

Muhtemelen bir yazım hatası var. Örneğin, Sales adlı bir veritabanında Müşteri adında bir tablonuz varsa, Sales..Customer olarak başvurabilirsiniz (Sales.dbo gibi sahip adı (dbo varsayılan sahip) dahil olmak üzere buna başvurmak daha iyidir) .Müşteri.

Satış ... yazdıysanız, aldığınız mesajı almış olabilirsiniz.


4

Yazım hatası olan bir yazım hatası olmadığından eminseniz, belki de yazım hatası olan yazım hatasıdır.

Hangi harmanlamayı kullanıyorsunuz? Kontrol et.


4

Tabloları güncellerken, takma ad yoluyla güncelleme alanınıza başvurmadığınızdan emin olun.

Ben sadece aşağıdaki kod ile hata vardı

update [page] 
set p.pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0

Set deyimdeki diğer ad referansını kaldırmak zorunda kaldım,

update [page] 
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0

4

Kısaltmaya çalıştığımda bunları çok fazla buldum, örneğin:

Table1 t1, Table2 t2 
where t1.ID = t2.ID

Şu şekilde değiştiriliyor:

Table1, Table2 
where Table1.ID = Table2.ID

Sorguyu çalıştırır ve hatayı atmaz.


3

Hata kodu

FROM                
    dbo.Category C LEFT OUTER JOIN           
    dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN          
    dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN          
    dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN 
    dbo.trainer ON dbo.trainer.TopicID =dbo.SubModule.subModuleID 

Çözüm Kodu

 FROM                
    dbo.Category C LEFT OUTER JOIN           
    dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN          
    dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN          
    dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN 
    dbo.trainer ON dbo.trainer.TopicID = SM.subModuleID 

Gördüğünüz gibi, hata kodunda dbo.SubModulezaten SM olarak tanımlanmıştır, ancak bir dbo.SubModulesonraki satırda kullanıyorum , bu nedenle bir hata oluştu. gerçek ad yerine beyan edilen adı kullan. Sorun çözüldü.


2

Bu sorunu vardı ve yanlış bir tablo diğer adı olduğu ortaya çıktı. Bunu düzeltmek sorunu çözdü.


2

Benimki şemayı yanlışlıkla Takma ad masasına koyuyordu:

SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1  -- oops!

2

Tablo takma adının önüne alan belirle, benim durumumda bu soruna neden olur.

Sağ Güncelleştirme Tablo1 Tablo1'den SomeField = t2.SomeFieldValue Ayarla t1 İç Birleştirme Table2'yi t2 olarak t1.ID = t2.ID

Yanlış Güncelleme Tablo1 t1.SomeField = t2.SomeFieldValue Table1'den ayarlayın t1 İç birleşim Table2'yi t2 olarak t1.ID = t2.ID


1

Ben P.PayeeName AS 'Payer' --, ve iki açıklama satırları bu hatayı attı


1

Aslında başkalarına masaya katılmayı unuttum, bu yüzden hatayı aldım

Bu şekilde olması gerekiyordu:

  CREATE VIEW reserved_passangers AS
  SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
  FROM dbo.Passenger, dbo.Reservation, dbo.Flight
  WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
  (dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum =562)

Ve bu şekilde değil:

  CREATE VIEW reserved_passangers AS
  SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
  FROM dbo.Passenger, dbo.Reservation
  WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
  (dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum = 562)

1

Hatayı aldığımda en iyi tavsiyem, tablo adlarını sorround için [] braketleri kullanmaktır, tabloların kısaltması bazen hatalara neden olur, (bazen tablo kısaltmaları iyi çalışır ... garip)


1

Bu hatayı alıyordum ve sadece sorunun nerede olduğunu göremedim. Tüm takma adlarımı ve sözdizimini iki kez kontrol ettim ve hiçbir şey yerinden çıkmadı. Sorgu her zaman yazdıklarıma benzerdi.

Ben sadece aşağıdaki (tekrar bir rapor .rdl dosyasından kopyalanmıştı) sorguyu yeniden yazmaya karar verdim, ve yine iyi çalıştı. Şimdi sorgulara baktığımda bana aynı görünüyorlar, ama yeniden yazdıklarım işe yarıyor.

Başka bir şey işe yaramazsa, denemeye değer olabileceğini söylemek istedim.


1

FROM tablosunu yazdığınızda bu hatalar kaybolacaktır. Yazmanızın altına FROM yazın ve Intellisense çalışacak ve çok parçalı tanımlayıcı çalışacaktır.


0

Bu sorunla karşılaştım ve çözdüm ama sizin ve benimki kod arasında bir fark var. Rağmen "çok parçalı tanımlayıcı bağlanamadı" ne olduğunu anlayabiliyorum düşünüyorum

Bu kodu kullandığımda

 select * from tbTest where email = sakira@gmail.com

Çok parçalı tanımlayıcı sorunuyla karşılaştım

ama e-posta adresi için tek tırnak kullandığımda çözüldü

 select * from tbTest where email = 'sakira@gmail.com'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.