Подтвердить что ты не робот

Как остановить SSMS 2012 от скриптов SP, используя sp_executesql

Я понимаю, что это очень похожий вопрос на Остановить SSMS из сценариев SP, используя sp_executesql?

Однако, похоже, они изменили поведение в SSMS 2012.

Если вы выбрали опцию "Проверить наличие", как в:

enter image description here

... теперь он генерирует IF NOT EXISTS для proc, который должен быть создан, , а как IF EXISTS для предыдущего обработчика drop, если, как я обычно делаю, я выбираю DROP и CREATE:

enter image description here

Это заставляет его script CREATE использовать sp_executesql. Это бессмысленно, так как вам не нужна проверка IF NOT EXISTS на CREATE, если DROP только что сбросил ее.

Кажется невозможным иметь одно без другого.

Любые идеи?

4b9b3361

Ответ 1

Вы не можете сделать это без динамического SQL, потому что хранимая процедура должна быть в своей собственной партии. Поэтому вы не можете сказать:

IF <some condition>
  <start a new batch>

Единственный способ сохранить это в той же партии - использовать sp_executesql.

Если вы собираетесь script DROP и CREATE одновременно, просто сделайте это без проверки существования объекта. Это даст вам:

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

Кого волнует, если DROP терпит неудачу? (Этого не должно быть, потому что вы просто скриптировали его!)

Если вы создаете сценарий для другой системы, которая может иметь объект, вы получите сообщение об ошибке для DROP, когда это не так, но CREATE все равно произойдет, поэтому вы можете игнорировать DROP. Если вы действительно хотите, вы можете вручную обернуть операторы DROP в TRY/CATCH, но я не думаю, что это необходимо.

Если вам нужно сделать это для большого количества процедур или вам действительно нужен процесс, чтобы не генерировать доброкачественные ошибки, я предлагаю вам отказаться от примитивных сценариев Studio Studio и использовать для этого сторонний инструмент. Они уже рассмотрят многие проблемы, с которыми вы еще не сталкивались, но будут. Я писал об этом:

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

Ответ 2

Ближе всего вы можете перейти к этой функции: перейти к инструментам, параметрам, обозревателю объектов SQL Server, сценариям, а затем установить флажок "Проверить для существующего объекта на false".

Недостаток заключается в том, что если вы это сделаете, то капли и создания всегда будут пытаться упасть, даже если объект не существует. Идеальное решение было бы настройкой, которая позволила бы вашему script выглядеть как пример ниже для создания представлений, процедур и пользовательских функций.

/****** 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

Короче, если движок сценариев думает о падении и создает вместе при проверке существования объекта, ему не нужно ставить условие на создание.

Ответ 3

Я нашел хорошее решение этой проблемы. При написании сценариев вы должны сделать "два прохода". Во время первого прохода выберите опции "Проверить наличие" и только для DROP script. Затем, на втором проходе, отмените выбор для проверки наличия и выберите CREATE script. Кроме того, используйте параметр "Добавить в файл". Затем при запуске сценариев генерации на втором пропуске снимите флажок "Переписать файл". Это будет работать, только если вы создаете отдельный файл для каждого объекта.

Ответ 4

Я также боролся с той же проблемой. Если вам нужно script удалить объекты для всей базы данных, вы можете рассмотреть ApexSQL Script. Я попробовал несколько инструментов, и ApexSQL скриптировал объекты именно так, как мне было нужно. (если объект существует, затем отбросьте. создайте объект). Я считаю, что он также работает из командной строки. Обратите внимание, что это shareware; Я использовал только оценочную версию, потому что мне это только нужно было несколько раз.

Ниже приведен пример вывода для процедуры после некоторой конфигурации.

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

Ответ 5

Наконец, после поиска множества статей я нашел решение, что

scripting вы должны сделать "два прохода. Во время первого прохода,

  • выберите опции "Проверить наличие" и только для DROP script.
  • Затем на втором проходе, de-select выберите "Проверить существование" и выберите CREATE script.
    • Кроме того, используйте опцию Append To File. Затем при запуске сценариев генерации на втором проходе снимите флажок "Overwrite File". Это будет работать, только если вы создаете отдельный файл для каждого объекта.