簡體   English   中英

找不到該對象,因為它不存在或您沒有權限。 SQL Server 錯誤

[英]Cannot find the object because it does not exist or you do not have permissions. Error in SQL Server

我有一個數據庫和一個 Sql 腳本,用於將一些字段添加到數據庫中名為“Products”的表中。

但是當我執行此腳本時,出現以下錯誤:

Cannot find the object "Products" because it does not exist or you do not have permissions

為什么會發生錯誤,我應該如何解決?

我找到了為什么會發生這種情況的原因。 用戶具有適當的權限,但存儲過程包含一個TRUNCATE語句:

TRUNCATE TableName

由於TRUNCATE刪除項目而不記錄,您(顯然)需要提升權限才能執行包含它的存儲過程。 我們將聲明更改為:

DELETE FROM TableName

...錯誤消失了!

您確定要針對正確的數據庫執行腳本嗎? 在 SQL Server Management Studio 中,您可以在其中一個工具欄上的下拉框中更改正在運行查詢的數據庫,或者您可以使用以下命令開始查詢:

USE SomeDatabase

這也可能是由於引用表(例如[dbo.Product]而不是[dbo].[Product]出現拼寫錯誤而發生的。

您在其下執行此腳本的用戶是否甚至看到該表?

select top 1 * from products

你有任何輸出嗎?

如果是:該用戶是否有權修改表,即執行諸如ALTER TABLE等 DDL 腳本? 通常,普通用戶沒有這種提升的權限。

也有可能您在登錄架構中創建了“產品”,並且您試圖在不同的架構(可能是 dbo)中執行相同的操作

解決此問題的步驟

1) 打開管理工作室 2) 在資源管理器中找到對象並確定您的對象所在的架構? (它是您的對象名稱之前的文本)。 在下面的圖像中,它的“dbo”和我的對象名稱是操作狀態

突出顯示的部分是架構名稱

如果您看到它類似於“yourcompanydoamin\\yourloginid”,那么您應該可以修改該特定架構的權限,而不是任何其他架構。

您可以參考“SQL Server 中的所有權和用戶架構分離”

在腳本中查找任何 DDL 操作。 也許用戶沒有運行更改的訪問權限。

就我而言,它是SET IDENTITY_INSERT tblTableName ON

您可以為整個數據庫或僅為表添加db_ddladmin來解決此問題(或更改腳本)

-- give the non-ddladmin user INSERT/SELECT as well as ALTER:
GRANT ALTER, INSERT, SELECT ON dbo.tblTableName TO user_name;

您可以右鍵單擊該過程,選擇屬性並查看授予您登錄 ID 的權限。 然后,您可以手動檢查“執行”並更改 proc 的權限。

或者將其編寫為:

GRANT EXECUTE ON OBJECT::dbo.[PROCNAME]
    TO [ServerInstance\user];

GRANT ALTER ON OBJECT::dbo.[PROCNAME]
    TO [ServerInstance\user];

這可能是一個許可問題。 用戶至少需要 ALTER 權限才能截斷表。 另一種選擇是調用 DELETE FROM 而不是 TRUNCATE TABLE,但此操作較慢,因為它寫入日志文件,而 TRUNCATE 不寫入日志文件。

所需的最低權限是對 table_name 的 ALTER。 TRUNCATE TABLE 權限默認授予表所有者、sysadmin 固定服務器角色的成員以及 db_owner 和 db_ddladmin 固定數據庫角色,並且不可轉讓。 但是,您可以將 TRUNCATE TABLE 語句合並到一個模塊(如存儲過程)中,並使用 EXECUTE AS 子句向該模塊授予適當的權限。

我一直在嘗試將表從 PROD 復制到 DEV,但出現錯誤:“找不到對象 X,因為它不存在或您沒有權限。”

但是,該表確實存在,並且我以 sa 身份運行,因此我確實有權限。

問題實際上出在 CONTRAINTS 上。 幾個月前,我將 DEV 上的表重命名為 old_XXX。 但是,當我嘗試從 PROD 復制原始約束時,默認約束名稱發生沖突。

錯誤信息具有誤導性

就我而言,我在與我期望的用戶不同的用戶下運行。

我有'DRIVER={SQL Server};SERVER=...;DATABASE=...;Trusted_Connection=false;User Id=XXX;Password=YYY'作為我傳遞給pypyodbc.connect()的連接字符串,但是連接仍在使用運行該腳本的 Windows 用戶的憑據(我使用 SQL Server Profiler 並通過嘗試無效的 uid/密碼組合驗證了這一點 - 這沒有導致預期的錯誤)。

我決定不再深入研究這個問題,因為切換到這種更好的連接方式解決了這個問題:

conn = pypyodbc.connect(driver='{SQL Server}', server='servername', database='dbname', uid='userName', pwd='Password')

分享我的案例,希望能有所幫助。

在我的情況下MY_PROJ.Database->MY_PROJ.Database.sqlproj我不得不把這個:

<Build Include="dbo\Tables\MyTableGeneratingScript.sql" />

在我的情況下,我的本地主機上的 sql server 版本高於生產服務器上的版本,因此一些新變量被添加到本地主機上生成的腳本中。 這首先導致創建表時出錯。 由於創建表失敗,后續對“NON EXISITING”表的查詢也失敗。 幸運的是,在長長的 sql 錯誤列表中,我發現這個“OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF”是導致我的問題的腳本中的新變量。 我進行了搜索和替換,錯誤消失了。 希望它可以幫助某人。

TRUNCATE 語句是我的第一個問題,很高興在這里找到解決方案。 但是我正在使用 SSIS 並嘗試從另一個數據庫加載數據,並且在使用 IDENTITY 創建自動遞增 ID 的任何表上失敗並出現相同的錯誤。 如果我自己編寫腳本,我首先需要使用命令SET IDENTITY_INSERT tablename ON ,然后在表更新完成后使用SET IDENTITY_INSERT tablename OFF 但這需要對表的 ALTER 權限,而我沒有。 因此,表加載時 SSIS 中的錯誤消息(即使上一步剛剛刪除了表中的所有數據。)

例如,當您在 Go 中使用像 GORM ( https://gorm.io/ ) 這樣的 ORM 時,您會收到此錯誤。

當您嘗試創建結構並意外傳遞 ID(主鍵)時,盡管它是自動插入的。

Visual Studio Code 等功能豐富的 IDE 很容易出現這種錯誤:

if tx := db.Create(&myStruct{
    Ts:                Time.Now(),
    ID:                42,
}); tx.Error != nil {
    t.Fatal(tx.Error)
}

您仍然可以通過 Visual Studio Code 使用自動填充,但刪除模型主鍵的條目:

if tx := db.Create(&myStruct{
    Ts:                Time.Now(),
}); tx.Error != nil {
    t.Fatal(tx.Error)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM