Sql-Server
SQL Server 表名以 # 開頭,在使用者數據庫中,不在 tempdb 中,不是臨時表
不知何故,幾十年前,在我們的數據庫中創建了一個以
#
. 它顯示在應用程序數據庫下的對象資源管理器中,而不是tempdb
. 出於某種原因,Azure 不會像這樣導入數據庫。我們不能刪除它、重命名它或與之互動。我已經嘗試過從對象資源管理器中刪除、*腳本拖放、從 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?
鑑於:
sp_rename
使用對象名稱而不是對象 ID,- 我們不能使用對象名稱,因為它以 a 開頭,
#
並且被解釋為具有特殊含義並且處理方式不同,- 所有其他選項都已用盡
您應該嘗試通過專用管理控制台 (DAC) 連接直接編輯底層系統目錄表:
- 獲取該
object_id
表的。- 在單使用者模式下重啟實例。這是為了能夠直接更新系統表(即不需要使用 DAC 連接)。
- 通過專用管理控制台連接進行連接。您可以通過在命令提示符視窗中執行以下命令在 SQLCMD 互動式會話中執行此操作:
C:\> SQLCMD -A -E
或者,使用以下命令直接連接到數據庫:
C:\> SQLCMD -A -E -d {database_name}
- 在該數據庫中,嘗試以下操作:
UPDATE sys.objects$ {enter} SET [name] = N'obsolete' {enter} WHERE [object_id] = {ye_olde_object_id}; {enter} GO {enter}
在您輸入
GO {enter}
.**直接編輯系統目錄表時請謹慎,不要對這樣做的想法感到太自在。只有在絕對沒有其他方法可以解決問題時才應該這樣做(例如這裡的案例)。**避免直接編輯可能有幾個原因,但最初想到的兩個原因是:
- 就像我們創建的數據模型一樣,可能有一些我們不知道的事情如何工作的規則和工作流程(例如,非規範化、管理跨各種表的數據狀態的“業務”規則等)
- 如果您遇到問題並簽訂了支持契約(我沒有看到支持協議的條款,但我很難相信這種語言不會出現在那裡)
@Paul Randal在對我的相關答案的評論中證實:“手動編輯系統表不可撤銷地在數據庫的引導頁面中設置一個標誌,將您的數據庫標記為已以這種方式編輯,並且 CSS 可能決定不提供幫助如果您隨後對該數據庫有問題。”