2012-05-16 23 views
21

停止SSMS 2012從腳本的SP我意識到這是Stop SSMS from scripting SPs using sp_executesql?如何使用sp_executesql

一個非常類似的問題。然而,他們似乎已經改變了與2012年SSMS

行爲如果你有「檢查對於存在」選項中選擇,如:

enter image description here

...現在生成IF NOT EXISTS爲將要創建的PROC,以及爲我˚F存在以前下降PROC,如果像我通常做,我選擇刪除並創建選項:

enter image description here

這迫使腳本在CREATE使用sp_executesql。這是毫無意義的,因爲如果DROP剛剛刪除它,你不需要對CREATE進行IF NOT EXISTS檢查。

似乎不可能有一個沒有另一個。

任何想法?

回答

8

如果沒有動態SQL,則無法執行此操作,因爲存儲過程必須位於其自己的批處理中。所以你不能說:

IF <some condition> 
    <start a new batch> 

只有這樣,才能保持在同一批次使用sp_executesql

如果您要同時編寫DROPCREATE,只需在沒有檢查對象存在的情況下執行即可。這會給你:

DROP PROCEDURE ...; 
GO 
CREATE PROCEDURE ...; 
GO 

誰在乎DROP失敗? (它不應該,因爲你只是從它的腳本!)

如果你正在編寫腳本到其他的系統,威力有對象,你會當它不會爲DROP的錯誤信息,但CREATE仍會發生,因此您可以忽略DROP錯誤。如果你真的想要你可以在TRY/CATCH中手動包裝DROP聲明,但我不認爲這是必要的。

如果您需要爲很多過程執行此操作,或者如果您確實需要該過程不會生成良性錯誤,那麼我建議您放棄Management Studio的原始腳本選項並使用第三方工具。他們已經處理了許多你還沒有遇到的問題,但會。我的博客上講述這個:

http://bertrandaaron.wordpress.com/2012/04/20/re-blog-the-cost-of-reinventing-the-wheel/

+0

感謝您 - 我懷疑這一點。我真正想要的是IF EXISTS和IF NOT EXISTS的選項。我現在可以忽略DROP錯誤,但是這些腳本是通過自動過程運行的,並且在某些時候我需要解析腳本日誌來檢查錯誤。他們似乎已經做出了這一改變的逆行步驟之一。 – ChrisA

+0

他們更新了措辭(這可能部分是我的錯)。請參閱http://connect.microsoft.com/SQLServer/feedback/details/624075/include-if-not-exists-clause-impacts-drop-scripting http://connect.microsoft.com/SQLServer/feedback/details/ 242799/ssms-certain-scripting-options-yield-dynamic-sql and https://connect.microsoft.com/SQLServer/feedback/details/242795/ssms-certain-scripting-options-do-not-work-for-修改 –

+3

是的,我沒有爲措辭煩惱。這是事實,如果我想要IF EXISTS(以防止DROP錯誤),我也被迫在創建時使用IF NOT EXISTS,這反過來又迫使創建成爲sp_executesql的一個參數,我也不會不要 - 因爲任何無意的錯別字都不會產生明顯的錯誤。之前沒有問題 - IF EXISTS在默認情況下存在,我沒有打開IF NOT EXISTS。在*不*有IF EXISTS一個單獨的選項,對我來說現在比SQL08更糟糕。 – ChrisA

5

你可以得到這個功能最接近的是工具,選項時,SQL Server對象資源管理器,腳本走,然後設置檢查對象存在的假。

缺點是,如果你這樣做,那麼即使對象不存在,刪除和創建也將總是嘗試刪除。理想的解決方案是讓您的腳本看起來像下面的示例創建視圖,過程和用戶​​定義函數的設置。

/****** Object: View [dbo].[vEmployees] Script Date: 9/14/2012 9:18:57 AM ******/ 
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vEmployees]')) 
DROP VIEW [dbo].[vEmployees] 
GO 

CREATE VIEW [dbo].[vEmployees] 
AS 
    SELECT DISTINCT 
     Employees.EmployeeID, 
     FirstName, 
     LastName 
    from 
     Employees 
      JOIN Sales on Employees.EmployeeID=Sales.EmployeeID 
GO 

總之,如果腳本引擎認爲下降和檢查對象的實存它不需要把條件對創建共同創造。

0

我也在努力解決同樣的問題。如果您需要編寫整個數據庫的對象腳本,則可能需要考慮ApexSQL腳本。我嘗試了幾種工具,並且ApexSQL完全按照我需要的方式編寫了這些對象。 (如果存在對象,則刪除,創建對象)。我相信它也可以在命令行中使用。請注意,它是共享軟件;我只使用評估版本,因爲我只需要它少數幾次。

下面是一些配置後的過程輸出示例。

IF (EXISTS(SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[myProcedure]') AND [type]='P')) 
DROP PROCEDURE [dbo].[myProcedure] 
GO 

SET ANSI_NULLS ON 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE PROCEDURE dbo.myProcedure 
AS 
    select 1 as a 
GO 
1

我找到了一個很好的解決方案來解決這個問題。 腳本編寫時,您必須進行「兩遍」。 在第一遍中,選擇選項以檢查是否存在AND僅用於DROP腳本。 然後,在第二遍中,取消選中檢查存在的選項並選擇CREATE腳本。另外,使用選項追加到文件。然後,在第二遍上運行生成腳本時,取消選中「覆蓋文件」選項。這隻有在您爲每個對象生成單獨的文件時纔有效。

0

搜索很多文章後,終於讓我找到解決方案,

您必須「兩道」scripting。在第一遍

  • 選擇相應選項,檢查它是否存在以及只有DROP腳本。
  • 然後,在第二遍,de-select選擇檢查是否存在並選擇CREATE腳本。
    • 另外,使用選項Append To File。然後在第二遍上運行生成腳本時,取消選中"Overwrite File"的選項。這隻有在您爲每個對象生成單獨的文件時纔有效。
+0

這與以前的答案相同 – Pedro