'ตัวระบุหลายส่วน' คืออะไรและเหตุใดจึงไม่สามารถผูกมัดได้


138

ฉันได้รับข้อผิดพลาดเหล่านี้อย่างต่อเนื่องเมื่อพยายามอัปเดตตารางตามตารางอื่น ฉันเขียนข้อความค้นหาใหม่เปลี่ยนลำดับของการรวมเปลี่ยนการจัดกลุ่มและในที่สุดก็ใช้งานได้ แต่ฉันไม่ค่อยเข้าใจ

'ตัวระบุหลายส่วน' คืออะไร?
เมื่อใดที่ 'ตัวระบุหลายส่วน' ไม่สามารถผูกมัดได้?
มันผูกพันกับอะไรอยู่แล้ว?
ข้อผิดพลาดนี้จะเกิดขึ้นในกรณีใดบ้าง?
วิธีที่ดีที่สุดในการป้องกันคืออะไร?

ข้อผิดพลาดเฉพาะจาก SQL Server 2005 คือ:

ไม่สามารถผูกตัวระบุหลายส่วน "... " ได้

นี่คือตัวอย่าง:

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

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

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

ข้อผิดพลาดจริง:

ข่าวสารเกี่ยวกับ 4104 ระดับ 16 สถานะ 1 บรรทัดที่ 3 ตัวระบุหลายส่วน "dbBWKMigration.dbo.Company.COMPANYNAME" ไม่สามารถผูกมัดได้

คำตอบ:


103

ตัวระบุหลายส่วนคือคำอธิบายของเขตข้อมูลหรือตารางที่มีหลายส่วนเช่น MyTable SomeRow - หากไม่สามารถผูกมัดได้นั่นหมายความว่ามีบางอย่างผิดปกติ - ไม่ว่าคุณจะพิมพ์ผิดง่ายหรือสับสนระหว่าง ตารางและคอลัมน์ นอกจากนี้ยังอาจเกิดจากการใช้คำสงวนในชื่อตารางหรือเขตข้อมูลของคุณและไม่ล้อมรอบด้วย [] นอกจากนี้ยังอาจเกิดจากการไม่รวมคอลัมน์ที่ต้องการทั้งหมดในตารางเป้าหมาย

บางอย่างเช่นredgate sql promptนั้นยอดเยี่ยมสำหรับการหลีกเลี่ยงการพิมพ์ด้วยตนเอง (แม้กระทั่งการรวมอัตโนมัติตามคีย์ต่างประเทศ) แต่ก็ไม่ฟรี SQL server 2008 รองรับ intellisense นอกกรอบแม้ว่าจะยังไม่สมบูรณ์เท่ารุ่น redgate


6
ยังคงเป็นจริง: คำใบ้พิมพ์ผิดของคุณช่วยวันของฉัน
Stefan

ความคิดเห็นแบบประหยัดวันสำหรับผู้มาใหม่: เพียงตรวจสอบการพิมพ์ผิดของคุณบางครั้งก็เกิดขึ้นเมื่อคุณทำชิ้นส่วนเล็ก ๆ หายไป ในปัญหาของฉันมันเป็น OBJECT_ID (Schema.Table) โดยไม่มีเครื่องหมายคำพูดใด ๆ ในแบบสอบถามมากกว่า 50 บรรทัด
Abdullah Ilgaz

58

ที่จริงบางครั้งเมื่อคุณกำลังปรับปรุงตารางหนึ่งจากข้อมูลของตารางอื่นผมคิดว่าหนึ่งในปัญหาที่พบบ่อยว่าสาเหตุข้อผิดพลาดนี้คือเมื่อคุณใช้ตัวย่อตารางของคุณไม่ถูกต้องหรือเมื่อพวกเขาไม่จำเป็นต้องใช้ ข้อความที่ถูกต้องอยู่ด้านล่าง:

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

ขอให้สังเกตว่าSomeFieldคอลัมน์จากตารางที่ 1ไม่ได้มีt1การคัดเลือกเป็นแต่เป็นเพียง t1.SomeFieldSomeField

หากมีคนพยายามอัปเดตโดยระบุt1.SomeFieldคำสั่งจะส่งคืนข้อผิดพลาดหลายส่วนที่คุณสังเกตเห็น


3
การเพิ่มนามแฝงของตารางในฟิลด์ Set ด้านหน้าทำให้เกิดปัญหานี้ในกรณีของฉัน
Malhaar Punjabi

1
นี่เป็นปัญหาของฉันเช่นกัน ฉันมี SET ABBREVIATION.My_Fieldเมื่อฉันต้องการSET.My_Field;
VSO

ฉันพบข้อผิดพลาดนี้ขณะใช้ OPENJSON `FROM cust c OUTER APPLY OPENJSON (cust.Addresses)` โยนข้อผิดพลาด `FROM Cust c OUTER APPLY OPENJSON (c.Addresses)` ให้
ผลลัพธ์

คุณอาจพบคำอธิบายจากsqlservertutorial.net/sql-server-basics/sql-server-update-joinเป็นประโยชน์:
CAtoOH

Amadelle กังฟูของคุณแข็งแกร่ง แก้ไขให้ฉัน !!
SHBouwhuis

17

มันคงพิมพ์ผิด มองหาสถานที่ในรหัสของคุณที่คุณเรียกว่า [schema] [TableName] (โดยทั่วไปที่ใดก็ได้ที่คุณอ้างอิงฟิลด์) และตรวจสอบว่าสะกดทุกอย่างถูกต้อง

โดยส่วนตัวแล้วฉันพยายามหลีกเลี่ยงสิ่งนี้โดยใช้นามแฝงสำหรับตารางทั้งหมดของฉัน ช่วยได้มากเมื่อคุณสามารถย่อชื่อตารางแบบยาวให้สั้นลงเป็นคำย่อของคำอธิบาย (เช่น WorkOrderParts -> WOP) และยังทำให้การสืบค้นของคุณอ่านง่ายขึ้น

แก้ไข: เป็นโบนัสเพิ่มเติมคุณจะประหยัดการกดแป้นพิมพ์ได้หลายครั้งเมื่อสิ่งที่คุณต้องพิมพ์คือนามแฝงสามหรือสี่ตัวอักษรเทียบกับชื่อสคีมาตารางและฟิลด์ทั้งหมดรวมกัน


6

Binding = การแสดงข้อความของคอลัมน์เฉพาะของคุณจะถูกแมปกับคอลัมน์ทางกายภาพในบางตารางในบางฐานข้อมูลบนเซิร์ฟเวอร์บางตัว

ตัวระบุหลายส่วนอาจเป็น: MyDatabase.dbo.MyTable หากคุณได้รับตัวระบุเหล่านี้ผิดแสดงว่าคุณมีตัวระบุหลายส่วนที่ไม่สามารถแมปได้

วิธีที่ดีที่สุดในการหลีกเลี่ยงคือการเขียนข้อความค้นหาในครั้งแรกหรือใช้ปลั๊กอินสำหรับสตูดิโอการจัดการที่ให้ intellisense จึงช่วยคุณได้โดยหลีกเลี่ยงการพิมพ์ผิด


5

คุณคงพิมพ์ผิด ตัวอย่างเช่นหากคุณมีตารางชื่อลูกค้าในฐานข้อมูลชื่อ Sales คุณสามารถอ้างถึงว่าเป็น Sales..Customer (แม้ว่าจะดีกว่าหากอ้างถึงรวมถึงชื่อเจ้าของ (dbo เป็นเจ้าของเริ่มต้น) เช่น Sales.dbo . ลูกค้า.

หากคุณพิมพ์ขาย ... ลูกค้าคุณอาจได้รับข้อความที่คุณได้รับ



4

เมื่ออัปเดตตารางตรวจสอบให้แน่ใจว่าคุณไม่ได้อ้างอิงฟิลด์การอัปเดตของคุณผ่านนามแฝง

ฉันเพิ่งมีข้อผิดพลาดกับรหัสต่อไปนี้

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 ดังนั้นจึงอ่านแบบนี้

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

ฉันพบว่าฉันได้รับสิ่งเหล่านี้เป็นจำนวนมากเมื่อฉันพยายามย่อเช่น:

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

เปลี่ยนเป็น:

Table1, Table2 
where Table1.ID = Table2.ID

ทำให้แบบสอบถามทำงานและไม่ทำให้เกิดข้อผิดพลาด




2

การเพิ่มนามแฝงของตารางในฟิลด์ Set ด้านหน้าทำให้เกิดปัญหานี้ในกรณีของฉัน

Right Update Table1 ตั้งค่า SomeField = t2.SomeFieldValue จาก Table1 t1 Inner Join Table2 เป็น t2 บน t1.ID = t2.ID

อัปเดต Table1 ผิดตั้งค่า t1.SomeField = t2.SomeFieldValue จาก Table1 t1 Inner Join Table2 เป็น t2 บน t1.ID = t2.ID



1

ที่จริงฉันลืมที่จะเข้าร่วมโต๊ะกับคนอื่นนั่นคือสาเหตุที่ฉันได้รับข้อผิดพลาด

สมมติว่าเป็นวิธีนี้:

  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)

ไม่ใช่วิธีนี้:

  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

รหัสข้อผิดพลาด

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 

รหัสโซลูชัน

 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 

อย่างที่คุณเห็นในรหัสข้อผิดพลาดdbo.SubModuleถูกกำหนดให้เป็น SM แล้ว แต่ฉันกำลังใช้dbo.SubModuleในบรรทัดถัดไปจึงเกิดข้อผิดพลาด ใช้ชื่อที่ประกาศแทนชื่อจริง แก้ไขปัญหา.


1

คำแนะนำที่ดีที่สุดของฉันเมื่อมีข้อผิดพลาดคือการใช้เครื่องหมายวงเล็บ [] กับชื่อตาราง sorround การย่อของตารางทำให้บางครั้งเกิดข้อผิดพลาด (บางครั้งตัวย่อตารางก็ใช้ได้ดี ... แปลก)


1

ฉันได้รับข้อผิดพลาดนี้และไม่เห็นว่าปัญหาอยู่ที่ใด ฉันตรวจสอบนามแฝงและไวยากรณ์ทั้งหมดของฉันซ้ำแล้วซ้ำอีกและไม่มีอะไรดูผิดปกติ ข้อความค้นหาคล้ายกับที่ฉันเขียนตลอดเวลา

ฉันตัดสินใจที่จะเขียนแบบสอบถามอีกครั้ง (เดิมฉันคัดลอกมาจากไฟล์รายงาน. rdl) ด้านล่างซ้ำอีกครั้งและมันก็ทำงานได้ดี เมื่อมองไปที่ข้อความค้นหาตอนนี้พวกเขาดูเหมือนกับฉัน แต่งานที่เขียนขึ้นใหม่ของฉัน

แค่อยากจะบอกว่ามันอาจจะคุ้มค่าถ้าไม่มีอะไรได้ผล


1

เมื่อคุณพิมพ์ตาราง FROM ข้อผิดพลาดเหล่านั้นจะหายไป พิมพ์ FROM ด้านล่างสิ่งที่คุณพิมพ์จากนั้น Intellisense จะทำงานและตัวระบุหลายส่วนจะทำงาน


0

ฉันประสบปัญหานี้และแก้ไขได้ แต่มีความแตกต่างระหว่างรหัสของคุณและของฉัน ทั้งๆที่ฉันคิดว่าคุณเข้าใจได้ว่าอะไรคือ "ตัวระบุหลายส่วนไม่สามารถผูกมัดได้"

เมื่อฉันใช้รหัสนี้

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

ฉันประสบปัญหาตัวระบุหลายส่วน

แต่เมื่อฉันใช้ใบเสนอราคาเดียวสำหรับที่อยู่อีเมลมันแก้ไขได้

 select * from tbTest where email = 'sakira@gmail.com'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.