ชื่อตาราง SQL Server ที่ขึ้นต้นด้วย # ในฐานข้อมูลผู้ใช้ไม่ใช่ใน tempdb ไม่ใช่ตาราง temp


13

#อย่างใดทศวรรษที่ผ่านมาตารางได้สร้างขึ้นในฐานข้อมูลของเราที่เริ่มต้นด้วย มันแสดงให้เห็นในวัตถุ Explorer tempdbที่ใต้ฐานข้อมูลของแอปไม่ได้อยู่ใน ด้วยเหตุผลบางอย่าง Azure จะไม่นำเข้าฐานข้อมูลเช่นนี้

เราไม่สามารถวางเปลี่ยนชื่อหรือโต้ตอบกับมันได้ ฉันได้ลองลบจาก Object Explorer, Script Drop , Renameจาก GUI และพวกมันไม่ทำงานเลย

เราอยู่บน SQL 2008 R2

drop table [*app*].[dbo]."#OBSOLETE";

Database name '*app*' ignored, referencing object in tempdb.
Msg 3701, Level 11, State 5, Line 1
Cannot drop the table '#OBSOLETE', because it does not exist or you do not 
have permission.

exec sp_rename "dbo.#OBSOLETE", "dbo.obsolete"

Msg 15225, Level 11, State 1, Procedure sp_rename, Line 338
No item by the name of 'dbo.#OBSOLETE' could be found in the current database '*app*', given that @itemtype was input as '(null)'.

เราจะฆ่าวัตถุนี้ได้อย่างไรเพื่อให้เราสามารถย้ายสิ่งนี้ไปยัง Azure ได้?


4
ลองใส่วงเล็บรอบ ๆ ชื่อตารางตอบเหมือนกันไหม
rvsc48

1
คุณลองใช้ฟังก์ชั่น QUOTENAME ได้ไหมถ้าวิธีแก้ปัญหาของ @ rvsc48 ไม่สามารถทำได้ (แม้ว่าฉันคิดว่ามันจะเป็นเช่นนั้น) docs.microsoft.com/en-us/sql/t-sql/functions/…
MguerraTorres

1
วงเล็บ: การตอบสนองแบบเดียวกัน
นั่นมันเป็นผู้ชายที่

1
โปรดเรียกใช้แบบสอบถามต่อไปนี้ใน DB SELECT [name], CONVERT(VARBINARY(128), [name]) FROM sys.tables WHERE [name] = N'#OBSOLETE';ที่มีตารางนี้การส่งออกและวางลงในคำถาม: ขอบคุณ
โซโลมอน Rutzky

2
ตัวเลือกอื่น (ที่ฉันไม่มีเวลาทดสอบ): 1)รับobject_idตารางนั้น 2)รีสตาร์ทอินสแตนซ์ในโหมดผู้ใช้คนเดียว 3)เชื่อมต่อผ่าน Dedicated Admin Connection 4)UPDATE sys.objects$ SET [name] =N'obsolete' WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}ในฐานข้อมูลที่ลองสิ่งที่ต้องการ คุ้มค่ากับการยิง ..
โซโลมอน Rutzky

คำตอบ:


16

ได้รับ:

  1. sp_rename ใช้ชื่อวัตถุแทนรหัสวัตถุ
  2. เราไม่สามารถใช้ชื่อวัตถุตั้งแต่เริ่มต้นด้วย a #และที่ตีความว่ามีความหมายพิเศษและจัดการแตกต่างกัน
  3. ตัวเลือกอื่น ๆ หมดแล้ว

คุณควรลองแก้ไขตารางแค็ตตาล็อกระบบโดยตรงผ่านการเชื่อมต่อ Dedicated Admin Console (DAC) :

  1. รับobject_idของตารางนั้น
  2. รีสตาร์ทอินสแตนซ์ในโหมดผู้ใช้คนเดียว นี่คือเพื่อให้สามารถอัปเดตตารางระบบโดยตรง (เช่นไม่ใช่ข้อกำหนดสำหรับการใช้การเชื่อมต่อ DAC)
  3. เชื่อมต่อผ่านการเชื่อมต่อคอนโซลผู้ดูแลระบบโดยเฉพาะ คุณสามารถทำได้ในเซสชันแบบโต้ตอบ SQLCMD โดยเรียกใช้สิ่งต่อไปนี้ในหน้าต่างพร้อมรับคำสั่ง:

    C:\> SQLCMD -A -E

    หรือเชื่อมต่อโดยตรงกับฐานข้อมูลโดยใช้:

    C:\> SQLCMD -A -E -d {database_name}
  4. ในฐานข้อมูลนั้นลองทำสิ่งต่อไปนี้:

    UPDATE sys.objects$ {enter}
    SET [name] = N'obsolete' {enter}
    WHERE [object_id] = {ye_olde_object_id}; {enter}
    GO {enter}

    GO {enter}มันจะไม่ดำเนินการคำสั่งจนกว่าคุณจะใส่ใน

โปรดระวังเมื่อแก้ไขตารางแคตตาล็อกของระบบโดยตรงและอย่าคุ้นเคยกับแนวคิดที่จะทำ นี่เป็นสิ่งที่ควรทำก็ต่อเมื่อไม่มีวิธีอื่นในการแก้ไขปัญหา (เช่นกรณีที่นี่) อาจมีสาเหตุหลายประการที่จะหลีกเลี่ยงการแก้ไขโดยตรง แต่ทั้งสองอย่างที่เริ่มนึกขึ้นมาคือ:

  • เช่นเดียวกับโมเดลข้อมูลที่เราสร้างขึ้นมีกฎและเวิร์กโฟลว์ที่เป็นไปได้สำหรับสิ่งต่าง ๆ ที่เราไม่รู้จัก (เช่น denormalization, กฎ "ธุรกิจ" ที่ควบคุมสถานะของข้อมูลในตารางต่างๆ ฯลฯ )
  • มีแนวโน้มที่จะทำการแก้ไขโดยตรงทำให้เกิดความรับผิดชอบของ Microsoft ในการช่วยเหลือคุณหากคุณประสบปัญหาและมีสัญญาการสนับสนุน (ฉันไม่เห็นข้อกำหนดของข้อตกลงการสนับสนุน แต่ฉันมีเวลายากที่จะเชื่อว่าภาษาดังกล่าวจะไม่อยู่ใน ที่นั่น)

    @Paul Randalยืนยันในความคิดเห็นเกี่ยวกับคำตอบที่เกี่ยวข้องของฉัน: "การแก้ไขตารางระบบด้วยตนเองโดยไม่สามารถตั้งค่าสถานะในหน้าบูตของฐานข้อมูลที่ทำเครื่องหมายฐานข้อมูลของคุณว่าถูกแก้ไขด้วยวิธีนี้และ CSS อาจตัดสินใจที่จะไม่ช่วย คุณถ้าคุณมีปัญหากับฐานข้อมูลในภายหลัง "


4
ฉันชอบคำตอบ แต่บางทีมันก็คุ้มค่าที่จะเพิ่มประโยคว่าทำไมมันถึงอันตราย
โจ Obbish

@ JoeObbish ขอบคุณและคำแนะนำที่ดี ฉันจะพยายามเพิ่มบางสิ่งในวันพรุ่งนี้
โซโลมอน Rutzky

2
@JoeObbish ฉันเพิ่งเพิ่มบางสิ่ง เพียงพอหรือไม่
โซโลมอน Rutzky
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.