2012-05-16 5 views
21

Comprendo que esto es una pregunta muy similar a Stop SSMS from scripting SPs using sp_executesql?cómo dejar de SSMS 2012 del SP de secuencias de comandos utilizando sp_executesql

Sin embargo, parece que han cambiado el comportamiento con SSMS 2012.

Si usted tiene la 'Comprobar opción existencia' de seleccionados, como en:

enter image description here

... ahora genera un SI NO EXISTE para el proc a punto de ser creado, , así como un I F existe para el proc caída anterior, si, como de costumbre, selecciono la gota y la opción Crear:

enter image description here

Esto obliga a la secuencia de comandos crea mediante sp_executesql. No tiene sentido, ya que no necesita la verificación IF NOT EXISTS en el CREATE, si el DROP acaba de soltarlo.

Parece imposible tener uno sin el otro.

¿Alguna idea?

Respuesta

8

No puede hacer esto sin el SQL dinámico porque un procedimiento almacenado tiene que estar en su propio lote. Por lo tanto no se puede decir:

IF <some condition> 
    <start a new batch> 

La única forma de evitar que en el mismo lote es utilizar sp_executesql.

Si va a crear el script DROP y CREATE simultáneamente, simplemente hágalo sin la comprobación de la existencia del objeto. Esto le dará:

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

A quién le importa si el DROP falla? (No debería, debido a que sólo mediante scripts de ella!)

Si estás secuencias de comandos para este otro sistema que fuerza tiene el objeto, obtendrá un mensaje de error para el DROP cuando no lo hace , pero el CREATE seguirá ocurriendo, por lo que puede ignorar los errores DROP. Si realmente lo desea, puede ajustar manualmente las declaraciones DROP en TRY/CATCH, pero no creo que sea necesario.

Si necesita hacer esto para muchos procedimientos, o si realmente necesita que el proceso no genere errores benignos, le sugiero que abandone las opciones de scripts originales de Management Studio y use una herramienta de terceros para esto. Ya habrán lidiado con muchos de los problemas que todavía no te has encontrado, pero lo harán. Me escribió en su blog acerca de esto:

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

+0

Gracias por esto, lo sospeché. Lo que realmente quiero es una opción tanto para IF EXISTS como IF IF EXISTS. Por el momento, puedo ignorar el error DROP, pero estos scripts se ejecutan mediante un proceso automático, y en algún momento necesitaré analizar los registros del script para verificar si hay errores. Parece que hicieron uno de sus pasos retrógrados con este cambio. – ChrisA

+0

Se actualizó la redacción (que podría ser en parte mi culpa). Consulte 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 y https://connect.microsoft.com/SQLServer/feedback/details/242795/ssms-certain-scripting-options-do-not-work-for- modificar –

+3

Sí, no me molesta la redacción. Es el hecho de que si quiero IF EXISTS (para evitar el error DROP), también me veo forzado a tener IF IF EXISTS en la creación, lo que a su vez fuerza a create a ser un argumento para sp_executesql, que también utilizo 't desea, ya que cualquier error tipográfico inadvertido no generará errores obvios. Antes todo estaba bien - el IF EXISTS estaba allí por defecto, y no tenía activado IF NOT EXISTS. En * no * tener IF existe una opción separada, para mí ahora es peor que con SQL08. – ChrisA

5

Lo más cerca que se puede llegar a esta funcionalidad es ir debajo de las herramientas, opciones, el Explorador de objetos de SQL Server, secuencias de comandos, a continuación, establezca la opción Buscar objeto existente en false.

El inconveniente es que si haces esto, entonces las gotas y las creaciones siempre intentarán caer incluso si el objeto no existe. La solución ideal sería una configuración que permitiera que su secuencia de comandos se asemejara al ejemplo siguiente para crear Vistas, Procedimientos y Funciones definidas por el usuario.

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

En resumen, si el motor de scripting piensa de la gota y crear juntos en la comprobación de existencia de objetos que no se tenga que poner la condición en la creación.

0

También tuve problemas con el mismo problema. Si necesita guiar los objetos para una base de datos completa, es posible que desee considerar ApexSQL Script. Probé varias herramientas y ApexSQL creó los objetos exactamente como lo necesitaba. (si el objeto existe, a continuación, suelte, cree el objeto). Creo que también funciona desde la línea de comandos. Tenga en cuenta que es shareware; Solo he usado la versión de evaluación porque solo la necesitaba un puñado de veces.

A continuación se muestra un ejemplo de la salida de un procedimiento después de alguna configuración.

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

Encontré una buena solución a este problema. Debe hacer "dos pasadas" al crear scripts. Durante la primera pasada, seleccione las opciones para Comprobar la existencia Y solo para la secuencia de comandos DROP. Luego, en la segunda pasada, anule la selección de la opción Verificar existencia y seleccione la secuencia de comandos CREAR. Además, use la opción Agregar al archivo. Luego, al ejecutar las secuencias de comandos generar en la segunda pasada, desmarque la opción para "Sobrescribir archivo". Esto solo funcionará si está generando un archivo separado para cada objeto.

0

Finalmente después de buscar muchos artículos que he encontrado la solución

usted debe hacer "dos pasos" cuando scripting. Durante la primera pasada ,

  • seleccionar las opciones para Comprobar la existencia y por sólo el guión DROP.
  • Luego, en el segundo pase, de-select la opción de Verificar la existencia y seleccione el script CREATE.
    • Además, utilice la opción Append To File. Luego, al ejecutar los scripts de generación en el segundo pase, desmarque la opción "Overwrite File". Esto solo funcionará si está generando un archivo separado para cada objeto.
+0

Esto es idéntico a una respuesta anterior – Pedro

Cuestiones relacionadas