Apa itu 'pengenal multi-bagian' dan mengapa tidak bisa diikat?

138

Saya terus-menerus mendapatkan kesalahan ini ketika saya mencoba memperbarui tabel berdasarkan tabel lain. Saya akhirnya menulis ulang kueri, mengubah urutan gabungan, mengubah beberapa pengelompokan, dan kemudian berhasil, tetapi saya tidak begitu mengerti.

Apa itu 'pengidentifikasi multi-bagian'?
Kapan 'pengidentifikasi multi-bagian' tidak dapat diikat?
Apa itu terikat?
Dalam kasus apa kesalahan ini terjadi?
Apa cara terbaik untuk mencegahnya?

Galat khusus dari SQL Server 2005 adalah:

Pengidentifikasi multi-bagian "..." tidak dapat diikat.

Berikut ini contohnya:

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

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

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

Kesalahan sebenarnya:

MSG 4104, Level 16, Negara Bagian 1, Baris 3 Pengidentifikasi multi-bagian "dbBWKMigration.dbo.Company.COMPANYNAME" tidak dapat terikat.

Bahkan Mien
sumber

Jawaban:

103

Pengidentifikasi multibagian adalah setiap deskripsi bidang atau tabel yang berisi banyak bagian - misalnya MyTable.SomeRow - jika tidak dapat diikat itu berarti ada yang salah dengannya - baik Anda salah ketik, atau kebingungan antara tabel dan kolom. Ini juga bisa disebabkan oleh penggunaan kata-kata yang dicadangkan dalam tabel atau nama bidang Anda dan tidak mengelilinginya dengan []. Ini juga dapat disebabkan oleh tidak menyertakan semua kolom yang diperlukan dalam tabel target.

Sesuatu seperti redgate sql prompt sangat bagus untuk menghindari keharusan mengetik ini secara manual (bahkan melengkapi otomatis bergabung berdasarkan kunci asing), tetapi tidak gratis. SQL server 2008 mendukung intellisense out of the box, meskipun tidak selengkap versi redgate.

Mengocok
sumber
6
Masih aktual: kesalahan ketik Anda menyelamatkan hari saya.
Stefan
Komentar penghemat hari untuk pendatang baru: cukup periksa kesalahan ketik Anda, terkadang itu terjadi ketika Anda kehilangan sebagian kecil. Dalam masalah saya, itu adalah OBJECT_ID (Schema.Table) tanpa tanda kutip dalam kueri 50+ baris.
Abdullah Ilgaz
58

Sebenarnya kadang-kadang ketika Anda memperbarui satu tabel dari data tabel lain, saya pikir salah satu masalah umum yang menyebabkan kesalahan ini, adalah ketika Anda menggunakan singkatan tabel Anda secara tidak benar atau ketika mereka tidak diperlukan . Pernyataan yang benar ada di bawah ini:

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

Perhatikan bahwa SomeFieldkolom dari Tabel1 tidak memiliki t1kualifikasi sebagai t1.SomeFieldtetapi adil SomeField.

Jika seseorang mencoba memperbaruinya dengan menentukan t1.SomeFieldpernyataan tersebut akan mengembalikan kesalahan multi-bagian yang telah Anda perhatikan.

amadelle
sumber
3
Menambahkan alias tabel di bidang Set depan menyebabkan masalah ini dalam kasus saya.
Malhaar Punjabi
1
Ini juga masalah saya. Saya memiliki SET ABBREVIATION.My_Field, ketika saya hanya perlu SET.My_Field;
VSO
Saya berlari ke kesalahan ini saat menggunakan OPENJSON. `FROM cust c OUTER APPLY OPENJSON (cust.Addresses)` melempar kesalahan. `FROM cust c OUTER APPLY OPENJSON (c. Addresses)` memberikan kembali hasil
Shaakir
Anda mungkin menemukan penjelasan dari sqlservertutorial.net/sql-server-basics/sql-server-update-join membantu:
CAtoOH
Amadelle, kung-fu Anda kuat. Ini memperbaikinya untuk saya !!
SHBouwhuis
17

Mungkin salah ketik. Cari tempat dalam kode Anda di mana Anda memanggil [skema]. [NamaTabel] (pada dasarnya di mana pun Anda mereferensikan bidang) dan pastikan semuanya dieja dengan benar.

Secara pribadi, saya mencoba menghindari ini dengan menggunakan alias untuk semua tabel saya. Ini sangat membantu ketika Anda dapat mempersingkat nama tabel panjang menjadi akronim dari deskripsinya (yaitu WorkOrderParts -> WOP), dan juga membuat kueri Anda lebih mudah dibaca.

Sunting: Sebagai bonus tambahan, Anda akan menghemat BANYAK penekanan tombol saat yang harus Anda ketik hanyalah alias tiga atau empat huruf vs. nama skema, tabel, dan bidang semuanya.

Letnan Frost
sumber
6

Binding = representasi tekstual Anda dari kolom tertentu dipetakan ke kolom fisik di beberapa tabel, di beberapa database, di beberapa server.

Pengidentifikasi multibagian bisa berupa: MyDatabase.dbo.MyTable. Jika Anda salah mendapatkan salah satu pengenal ini, maka Anda memiliki pengenal multibagian yang tidak dapat dipetakan.

Cara terbaik untuk menghindarinya adalah dengan menulis kueri dengan benar pada kali pertama, atau menggunakan plugin untuk studio manajemen yang menyediakan Intellisense dan dengan demikian membantu Anda dengan menghindari kesalahan ketik.

Mark S. Rasmussen
sumber
5

Anda mungkin salah ketik. Misalnya, jika Anda memiliki tabel bernama Pelanggan dalam database bernama Penjualan, Anda dapat merujuknya sebagai Penjualan..Pelanggan (meskipun lebih baik merujuk ke sana termasuk nama pemilik (dbo adalah pemilik default) seperti Sales.dbo .Pelanggan.

Jika Anda mengetik Penjualan ... Pelanggan, Anda mungkin telah menerima pesan yang Anda terima.

HLGEM
sumber
4

Jika Anda yakin bahwa ini bukan kesalahan pengetikan, mungkin itu adalah kesalahan pengetikan.

Pemeriksaan apa yang Anda gunakan? Periksa.

Pittsburgh DBA
sumber
4

Saat memperbarui tabel, pastikan Anda tidak mereferensikan bidang yang Anda perbarui melalui alias.

Saya baru saja mengalami kesalahan dengan kode berikut

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

Saya harus menghapus referensi alias dalam pernyataan set sehingga terbaca seperti ini

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

Saya menemukan bahwa saya mendapatkan banyak ini ketika saya mencoba menyingkat, seperti:

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

Mengubahnya menjadi:

Table1, Table2 
where Table1.ID = Table2.ID

Membuat kueri berfungsi dan tidak membuang kesalahan.

jo-mso
sumber
2

Saya mengalami masalah ini dan ternyata itu adalah alias tabel yang salah. Memperbaiki ini menyelesaikan masalah.

Matt Setter
sumber
2

Punyaku salah menempatkan skema di atas tabel Alias:

SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1  -- oops!
tidak diketahui
sumber
2

Menambahkan alias tabel di bidang Set depan menyebabkan masalah ini dalam kasus saya.

Kanan Perbarui Tabel1 Set SomeField = t2.SomeFieldValue Dari Tabel1 t1 Inner Gabung Tabel2 sebagai t2 On t1.ID = t2.ID

Salah Perbarui Tabel1 Set t1.SomeField = t2.SomeFieldValue Dari Tabel1 t1 Inner Bergabung dengan Tabel2 sebagai t2 On t1.ID = t2.ID

Malhaar Punjabi
sumber
1

Saya punya P.PayeeName AS 'Payer' --, dan dua baris komentar melemparkan kesalahan ini

Andrew Day
sumber
1

Saya benar-benar lupa untuk bergabung dengan tabel dengan yang lain itu sebabnya saya mendapat kesalahan

Seharusnya begini:

  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)

Dan bukan begini:

  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)
MT_Shikomba
sumber
1

Kode Kesalahan

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 

Kode Solusi

 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 

seperti yang Anda lihat, dalam kode kesalahan, dbo.SubModulesudah didefinisikan sebagai SM, tetapi saya menggunakan dbo.SubModuledi baris berikutnya, maka ada kesalahan. gunakan nama yang dideklarasikan, bukan nama sebenarnya. Masalah terpecahkan.

Onkar Vidhate
sumber
1

Saran terbaik saya ketika mengalami kesalahan adalah dengan menggunakan [] braquets untuk sorround nama tabel, singkatan tabel kadang-kadang menyebabkan kesalahan, (kadang-kadang singkatan tabel berfungsi dengan baik ... aneh)

ramnz.dll
sumber
1

Saya mendapatkan kesalahan ini dan tidak bisa melihat di mana masalahnya. Saya memeriksa ulang semua alias dan sintaks saya dan tidak ada yang terlihat salah. Kueri tersebut mirip dengan yang saya tulis sepanjang waktu.

Saya memutuskan untuk hanya menulis ulang kueri (saya awalnya telah menyalinnya dari file report .rdl) di bawah, lagi, dan itu berjalan dengan baik. Melihat kueri sekarang, mereka terlihat sama bagi saya, tetapi yang saya tulis ulang berfungsi.

Hanya ingin mengatakan bahwa itu mungkin layak dicoba jika tidak ada yang berhasil.

kerang
sumber
1

Saat Anda mengetik tabel FROM, kesalahan tersebut akan hilang. Ketik FROM di bawah apa yang Anda ketik maka Intellisense akan berfungsi dan pengidentifikasi multi-bagian akan berfungsi.

David Morrow
sumber
0

Saya menghadapi masalah ini dan menyelesaikannya tetapi ada perbedaan antara kode Anda dan kode saya. Meskipun menurut saya Anda dapat memahami apa itu "pengenal multi-bagian tidak dapat terikat"

Saat saya menggunakan kode ini

 select * from tbTest where email = [email protected]

Saya menghadapi masalah pengidentifikasi multi-bagian

tetapi ketika saya menggunakan kutipan tunggal untuk alamat email, itu terpecahkan

 select * from tbTest where email = '[email protected]'
Neloy Sarothi
sumber