2012-06-04 41 views
13

當我創建於2012年的SQL一個Visual Studio數據庫項目,並將其與現有的數據庫(使用比較模式)同步,我也同步SQL Server登錄之前就存在。 Visual Studio中生成的登錄下面的腳本:的Visual Studio數據庫項目:檢查是否SQL Server登錄創建它

CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass' 

當我嘗試發佈,其中該登錄存在服務器上生成的SQL,SQLCMD顯示我的錯誤:

The server principal my_user already exists. 

當我看由Visual Studio生成的SQL腳本,我發現許多對象都被包裝在IF EXISTS語句中,但是CREATE LOGIN未被包裝!

我試圖手動敷在SQL腳本項目,但後來該項目不建並有指向如果一個錯誤:

SQL70001: This statement is not recognized in this context. 

現在我該怎樣強制Visual Studio來生成使用IF EXISTS檢查的登錄創建腳本也不會失去同步功能?

+0

如何將用戶移除到預部署腳本中?只是一個猜測...... – abx78

+0

@ abx78:是的,我想過了,但是我還必須將該登錄的實際數據庫用戶創建移動到部署前(如果我不這樣做,Visual Studio會在我說my_db_user對my_user登錄有一個不好的引用)。再次 - 如果在將數據庫部署到數據庫之後,某人運行架構比較,則這些登錄名和用戶將像最初一樣再次出現在項目中。 – JustAMartin

+0

我不明白爲什麼模式比較發現登錄,如果它已經存在於目標中。 –

回答

21

更改腳本文件(* .SQL)爲無的生成操作屬性。這解決了這個問題。

生成操作屬性通過右鍵單擊Solution Explorer中的SQL文件,然後單擊屬性進行訪問。或者,在解決方案資源管理器中突出顯示該文件,然後按'F4'。

+2

這是愚蠢的答案。如果我們這樣做,這個文件在發佈時不會被執行!!!!!!!!!!!!!!!!!!!! – BJladu4

+1

這是美妙的答案。正是我在找什麼!!!!!!!!!!!!!!!!!!!!!!!!!!!!! – Matt

+4

@ BJladu4,你可以使用像這樣的':r。\ some-sql-file-set-to-none.sql'來執行另一個sql文件中的文件。還有,玩得很好@Matt,哈哈 – JohnnyFun

-1
IF NOT EXISTS 
(
SELECT [Column Name Where Username Is Stored] 
FROM [Table Name That Holds The Login's] 
WHERE name = 'my_user' 
) 
BEGIN 
CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass' 

ELSE.... 

然後,你可以寫一個else語句來處理它,但是你想這是否是更新密碼到新的或簡單地返回一個消息,說該用戶已經存在。請告訴我,如果您需要幫助編寫該部分。

+1

是的,我試過那個。如果在SQL管理工作室中使用它,但它在Visual Studio數據庫項目中的查詢中輸入時不起作用。它給出了一個錯誤(IF行被加下劃線的紅色):SQL70001:這個語句在這個上下文中不被識別。很顯然,Visual Studio數據庫項目不允許IF在CREATE ... – JustAMartin

+0

腳本正確,但編譯器在嘗試構建時不喜歡該腳本。只需右鍵單擊腳本文件並選擇「從解決方案中排除」。該項目將建立,它會在需要引用該文件時找到該文件。讓我知道這是不是一個可接受的解決方案。 – danmanallen

+0

@danmanallen我認爲你的解決方案在部署時不會起作用。 – abx78

0

我有完全同樣的問題,從我的解決辦法是有一個預先部署腳本刪除用戶:

IF EXISTS(SELECT TOP 1 1 FROM master.sys.server_principals WHERE name = 'my_user') BEGIN 
    DROP LOGIN [my_user] 
END 

的問題是,也許你已經更改了密碼,權限,或設置LOGIN [my_user]自創建以來,在丟棄並創建它之後,您將丟失該自定義設置。

1

不知道如果我理解正確的問題,但我來是因爲類似的情況在這裏。在浪費了幾個小時後,用「if」和「try catch」這裏是我的答案:

看着DacPac exclude users and logins on export or import我發現應該有一個選項排除登錄。我發現你可以爲數據庫項目更改發佈設置,但這些設置存儲在* .user文件中,我通常不會將其放入源代碼管理。進一步看,我發現命令行選項sqlpackage.exehttps://blogs.msdn.microsoft.com/ssdt/2015/02/23/new-advanced-publish-options-to-specify-object-types-to-exclude-or-not-drop/。這似乎工作相當不錯,也因爲你可以從的NuGet(見https://blogs.msdn.microsoft.com/ssdt/2016/08/22/releasing-ssdt-with-visual-studio-15-preview-4-and-introducing-ssdt-msbuild-nuget-package/)sqlpackage.exe得到。所以沒有任何方法可以在CI機器上構建並將結果部署到服務器。

編輯: 這是在VS2015與各自的SSDT。

4

對於任何人誰是尋找一個完整答案,這裏是我做過什麼:

  1. 在Visual Studio中,在您的登錄腳本右鍵單擊,或在我的情況下鏈接的服務器腳本。
  2. 點擊屬性
  3. Under Advanced - >構建動作,將其從構建更改爲
  4. 在您的PreDeployment腳本中,添加一行以運行此腳本。對我而言,我將鏈接的服務器腳本移動到與PreDeployment腳本相同的文件夾中。然後,我可以做

    :r .\linkedserver.sql

  5. 當您部署decpac,您的登錄腳本或鏈接服務器腳本將被成功執行。
+0

非常感謝Dongminator ..這真的很有幫助,它拯救了我的生命.. – Bharat

相關問題