sql-server - todos - tipos de procedimientos almacenados
Procedimientos almacenados/esquema DB en control de fuente (21)
¿Ustedes mantienen un seguimiento de los procedimientos almacenados y el esquema de la base de datos en su sistema de control de origen de elección?
Cuando haces un cambio (agregas una tabla, actualizas un proceso almacenado, ¿cómo logras que los cambios entren en control de la fuente?
Usamos SQL Server en el trabajo, y he comenzado a usar darcs para versionar, pero me gustaría tener curiosidad sobre las estrategias generales, así como sobre cualquier herramienta útil.
Edit: Wow, gracias por todas las grandes sugerencias, chicos! ¡Ojalá pudiera seleccionar más de una "Respuesta Aceptada"!
Almacenamos todo lo relacionado con una aplicación en nuestro SCM. Los scripts DB generalmente se almacenan en su propio proyecto, pero se tratan como cualquier otro código ... diseño, implementación, prueba, confirmación.
Creo que debería escribir un script que configure automáticamente su base de datos, incluidos los procedimientos almacenados. Esta secuencia de comandos debe colocarse en control de fuente.
Descubrí que, con mucho, la forma más fácil, rápida y segura de hacerlo es simplemente solucionar el problema y usar SQL Source Control de RedGate. Encriptado y almacenado en el repositorio en cuestión de minutos. Solo deseo que RedGate considere el producto como un líder de pérdida para que pueda tener un uso más generalizado.
Ejecuto un trabajo para guiarlo a una estructura de directorio formal.
El siguiente es el código VS2005, proyecto de línea de comando, llamado desde un archivo por lotes, que hace el trabajo. Teclas app.config al final del código.
Se basa en otro código que encontré en línea. Un poco difícil de configurar, pero funciona bien una vez que lo haces funcionar.
Imports Microsoft.VisualStudio.SourceSafe.Interop
Imports System
Imports System.Configuration
Module Module1
Dim sourcesafeDataBase As String, sourcesafeUserName As String, sourcesafePassword As String, sourcesafeProjectName As String, fileFolderName As String
Sub Main()
If My.Application.CommandLineArgs.Count > 0 Then
GetSetup()
For Each thisOption As String In My.Application.CommandLineArgs
Select Case thisOption.ToUpper
Case "CHECKIN"
DoCheckIn()
Case "CHECKOUT"
DoCheckOut()
Case Else
DisplayUsage()
End Select
Next
Else
DisplayUsage()
End If
End Sub
Sub DisplayUsage()
Console.Write(System.Environment.NewLine + "Usage: SourceSafeUpdater option" + System.Environment.NewLine + _
"CheckIn - Check in ( and adds any new ) files in the directory specified in .config" + System.Environment.NewLine + _
"CheckOut - Check out all files in the directory specified in .config" + System.Environment.NewLine + System.Environment.NewLine)
End Sub
Sub AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_RECURSYES + VSSFlags.VSSFLAG_DELNO
Try
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Add(fileFolderName, "", Flags)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("already exists") > 0 Then
Console.Write(ex.Message)
End If
End Try
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckIn()
AddNewItems()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_DELTAYES + VSSFlags.VSSFLAG_UPDUPDATE + VSSFlags.VSSFLAG_FORCEDIRYES + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkin("", fileFolderName, Flags)
Dim File As String
For Each File In My.Computer.FileSystem.GetFiles(fileFolderName)
Try
Proj.Add(fileFolderName + File)
Catch ex As Exception
If Not ex.Message.ToString.ToLower.IndexOf("access code") > 0 Then
Console.Write(ex.Message)
End If
End Try
Next
Proj = Nothing
db = Nothing
End Sub
Sub DoCheckOut()
Dim db As New VSSDatabase
db.Open(sourcesafeDataBase, sourcesafeUserName, sourcesafePassword)
Dim Proj As VSSItem
Dim Flags As Integer = VSSFlags.VSSFLAG_REPREPLACE + VSSFlags.VSSFLAG_RECURSYES
Proj = db.VSSItem(sourcesafeProjectName, False)
Proj.Checkout("", fileFolderName, Flags)
Proj = Nothing
db = Nothing
End Sub
Sub GetSetup()
sourcesafeDataBase = ConfigurationManager.AppSettings("sourcesafeDataBase")
sourcesafeUserName = ConfigurationManager.AppSettings("sourcesafeUserName")
sourcesafePassword = ConfigurationManager.AppSettings("sourcesafePassword")
sourcesafeProjectName = ConfigurationManager.AppSettings("sourcesafeProjectName")
fileFolderName = ConfigurationManager.AppSettings("fileFolderName")
End Sub
End Module
<add key="sourcesafeDataBase" value="C:/wherever/srcsafe.ini"/>
<add key="sourcesafeUserName" value="vssautomateuserid"/>
<add key="sourcesafePassword" value="pw"/>
<add key="sourcesafeProjectName" value="$/where/you/want/it"/>
<add key="fileFolderName" value="d:/yourdirstructure"/>
Elegimos hacer un script de todo, y eso incluye todos los procedimientos almacenados y los cambios de esquema. No se necesitan herramientas wysiwyg ni programas sofisticados de "sincronización".
Los cambios de esquema son fáciles, todo lo que necesita hacer es crear y mantener un solo archivo para esa versión, incluidos todos los cambios de esquema y datos. Este se convierte en el script de conversión de la versión x a la x + 1. Luego puede ejecutarlo contra una copia de seguridad de producción e integrarlo en su ''compilación diaria'' para verificar que funcione sin errores. Tenga en cuenta que es importante no cambiar ni eliminar los esquemas / datos ya escritos que cargan sql ya que puede terminar rompiendo cualquier sql escrito más tarde.
-- change #1234
ALTER TABLE asdf ADD COLUMN MyNewID INT
GO
-- change #5678
ALTER TABLE asdf DROP COLUMN SomeOtherID
GO
Para los procedimientos almacenados, elegimos un solo archivo por sproc, y usa el formulario drop / create. Todos los procedimientos almacenados se vuelven a crear al momento de la implementación. La desventaja es que si se realizó un cambio fuera del control de la fuente, el cambio se pierde. Al mismo tiempo, eso es cierto para cualquier código, pero su DBA debe ser consciente de esto. Esto realmente impide que personas ajenas al equipo se deshagan de sus procedimientos almacenados, ya que sus cambios se pierden en una actualización.
Al usar Sql Server, la sintaxis se ve así:
if exists (select * from dbo.sysobjects where id = object_id(N''[dbo].[usp_MyProc]'') and OBJECTPROPERTY(id, N''IsProcedure'') = 1)
drop procedure [usp_MyProc]
GO
CREATE PROCEDURE [usp_MyProc]
(
@UserID INT
)
AS
SET NOCOUNT ON
-- stored procedure logic.
SET NOCOUNT OFF
GO
Lo único que queda por hacer es escribir un programa de utilidad que clasifique todos los archivos individuales y cree un nuevo archivo con todo el conjunto de actualizaciones (como un único script). Para ello, primero agregue los cambios de esquema y vuelva a generar la estructura de directorios e incluya todos los archivos de procedimientos almacenados.
Como una ventaja para programar todo, mejorarás mucho al leer y escribir SQL. También puede hacer que todo este proceso sea más elaborado, pero este es el formato básico de cómo controlar el origen de todos los sql sin ningún software especial.
anexo: Rick tiene razón en que perderá permisos en los procedimientos almacenados con DROP / CREATE, por lo que es posible que necesite escribir otro script para volver a habilitar los permisos específicos. Este script de permisos sería el último en ejecutarse. Nuestra experiencia encontró más problemas con ALTER versos DROP / CREATE semántica. YMMV
En experiencias pasadas, he mantenido controlada la fuente de cambios en la base de datos de tal manera que para cada versión del producto, cualquier cambio en la base de datos siempre se generó y se almacenó en la versión en la que estamos trabajando. El proceso de creación en el lugar llevaría automáticamente la base de datos a la versión actual basada en una tabla en la base de datos que almacenó la versión actual para cada "aplicación". Una aplicación de utilidad .net personalizada que escribimos se ejecutaría y determinaría la versión actual de la base de datos, y ejecutaría cualquier nueva secuencia de comandos en orden de los números de prefijo de las secuencias de comandos. Luego, realizábamos pruebas unitarias para asegurarnos de que todo estuviera bien.
Almacenamos los scripts en el control de código fuente de la siguiente manera (estructura de carpetas a continuación):
Estoy un poco oxidado con las convenciones de nombres actuales sobre tablas y procedimientos almacenados, tan simples con mi ejemplo ...
[raíz]
[solicitud]
[versión]
[guión]
/guiones
Mi aplicación/
1.2.1 /
001.MyTable.Create.sql
002.MyOtherTable.Create.sql
100.dbo.usp.MyTable.GetAllNewStuff.sql
Con el uso de una tabla de Versiones que tomaría en cuenta la Aplicación y Versión, la aplicación restauraría la copia de seguridad de producción semanal y ejecutaría todos los scripts necesarios contra la base de datos desde la versión actual. Al usar .net, pudimos empaquetar fácilmente esto en una transacción y si algo fallaba, retrocedíamos y enviamos correos electrónicos, por lo que sabíamos que esa versión tenía scripts incorrectos.
Por lo tanto, todos los desarrolladores se asegurarán de mantener esto en el control de la fuente para que la versión coordinada se asegure de que todos los scripts que planeamos ejecutar en la base de datos se ejecuten correctamente.
Esta es probablemente más información de la que estaba buscando, pero funcionó muy bien para nosotros y, dada la estructura, fue fácil conseguir que todos los desarrolladores se sumaran.
Cuando llegara el día del lanzamiento, el equipo de operaciones seguiría las notas de la versión y recogería los scripts del control de fuente y ejecutaría el paquete contra la base de datos con la aplicación .net que usamos durante el proceso de creación nocturna, que automáticamente empaquetaría los scripts en las transacciones. algo falló, se retrotraería automáticamente y no se generaría ningún impacto en la base de datos.
En mi empresa, tendemos a almacenar todos los elementos de la base de datos en control de código fuente como scripts individuales, tal como lo haría con los archivos de código individuales. Todas las actualizaciones se hacen primero en la base de datos y luego se migran al repositorio de código fuente para que se mantenga un historial de cambios.
Como segundo paso, todos los cambios en la base de datos se migran a una base de datos de integración. Esta base de datos de integración representa exactamente lo que debería ser la base de datos de producción después de la implementación. También tenemos una base de datos de control de calidad que representa el estado actual de producción (o la última implementación). Una vez que todos los cambios se realizan en la base de datos de Integración, utilizamos una herramienta de diferencias de esquema (SQL Diff SQL for SQL Server) para generar un script que migrará todos los cambios de una base de datos a otra.
Hemos encontrado que esto es bastante efectivo ya que genera un solo script que podemos integrar fácilmente con nuestros instaladores. El mayor problema que tenemos a menudo es que los desarrolladores se olviden de migrar sus cambios a la integración.
Estoy de acuerdo con (y upvote) la práctica de Robert Paulson. Eso es asumiendo que usted tiene el control de un equipo de desarrollo con la responsabilidad y la disciplina para cumplir con esa práctica.
Para "forzar" eso en mis equipos, nuestras soluciones mantienen al menos un proyecto de base de datos de Visual Studio Team Edition para profesionales de bases de datos . Al igual que con otros proyectos en la solución, el proyecto de base de datos obtiene control de versiones. Hace que sea un proceso de desarrollo natural dividir todo en la base de datos en fragmentos mantenibles, "disciplinando" a mi equipo en el camino.
Por supuesto, al ser un proyecto de Visual Studio, no es casi perfecto. Hay muchas peculiaridades que te encontrarás que pueden frustrarte o confundirte. Se necesita un poco de comprensión sobre cómo funciona el proyecto antes de lograr que cumpla con sus tareas. Ejemplos incluyen
- desplegar datos desde archivos CSV .
- despliegue selectivo de datos de prueba basados en el tipo de compilación .
- Visual Studio falla al comparar bases de datos con cierto tipo de ensamblado CLR incrustado en .
- no hay medios de diferenciación entre las bases de datos de prueba / producción que implementan diferentes esquemas de autenticación: usuarios de SQL vs usuarios de Active Directory.
Pero para los equipos que no tienen la práctica de versionar sus objetos de base de datos, este es un buen comienzo. La otra alternativa famosa es, por supuesto, la serie de productos de SQL Server de Red Gate , que la mayoría de las personas que los utilizan consideran superior a la oferta de Microsoft.
Guíe todo (creación de objetos, etc.) y almacene esos guiones en control de fuente. ¿Cómo llegan los cambios? Es parte de la práctica estándar de cómo se hacen las cosas. ¿Necesitas agregar una tabla? Escribir un script CREATE TABLE. Actualiza un sproc? Edite el script de procedimiento almacenado.
Prefiero un script por objeto.
Hemos estado utilizando un enfoque alternativo en mi proyecto actual: no tenemos el archivo db bajo control de código fuente, sino que hemos estado usando una herramienta de diferencia de base de datos para realizar un script de los cambios cuando llegamos a cada lanzamiento.
Ha estado funcionando muy bien hasta ahora.
La solución que usamos en mi último trabajo fue numerar los scripts a medida que se agregaban al control de fuente:
01.CreateUserTable.sql
02.PopulateUserTable
03.AlterUserTable.sql
04.CreateOrderTable.sql
La idea era que siempre supiéramos qué orden ejecutar los scripts, y podríamos evitar tener que gestionar los problemas de integridad de datos que pudieran surgir si intentara modificar el script n. ° 1 (lo que presumiblemente causaría la falla de los INSERT en el n. ° 2).
Los procedimientos almacenados obtienen 1 archivo por sp con el estándar si existen instrucciones drop / create en la parte superior. Las vistas y las funciones también obtienen sus propios archivos, por lo que son más fáciles de versionar y reutilizar.
Para empezar, Schema es todo 1 script, luego haremos cambios de versión.
Todo esto se almacena en un proyecto de base de datos de estudio visual conectado a TFS (@ work o VisualSVN Server @ home para cosas personales) con una estructura de carpetas de la siguiente manera:
- proyecto
- funciones
- esquema
-- procedimientos almacenados
-- puntos de vista
Mantenemos los procedimientos almacenados en control de fuente. La forma en que nosotros (o al menos yo) lo hago es agregar una carpeta a mi proyecto, agregar un archivo para cada SP y copiarlo y pegarlo manualmente. Entonces cuando cambio el SP, manualmente necesito cambiar el archivo del control de fuente.
Me interesaría saber si las personas pueden hacer esto automáticamente.
Mantenemos los procedimientos almacenados en control de fuente.
Para los procesos, escriba los procesos con envoltorios de scripts en archivos sin formato y aplique los cambios desde esos archivos. Si se aplicó correctamente, puede verificar ese archivo y también podrá reproducirlo desde ese archivo.
Para los cambios de esquema, es posible que deba verificar los scripts para realizar los cambios que ha realizado de forma incremental. Escriba el guión, aplíquelo y luego instálelo. Luego puede crear un proceso para aplicar automáticamente cada guión de esquema en serie.
Recomiendo mantener el esquema y los procedimientos almacenados en el control de código fuente.
Mantener los procedimientos almacenados versionados les permite deshacerse cuando se determina que es problemático.
El esquema es una respuesta menos obvia dependiendo de lo que usted quiera decir. Es muy útil mantener el SQL que define sus tablas en control de fuente, para duplicar entornos (prod / dev / usuario, etc.).
Si está buscando una solución fácil y preparada, nuestro sistema Sql Historian utiliza un proceso en segundo plano para sincronizar automáticamente los cambios de DDL a TFS o SVN, transparentes para cualquiera que realice cambios en la base de datos. En mi experiencia, el gran problema es mantener el código en control de fuente con lo que se cambió en tu servidor, y eso es porque generalmente tienes que confiar en las personas (¡incluso los desarrolladores!) Para cambiar su flujo de trabajo y recordar verificar sus cambios. después de que ya lo hayan hecho en el servidor. Poner esa carga en una máquina hace que la vida de todos sea más fácil.
Similar a Robert Paulson, arriba, nuestra organización mantiene la base de datos bajo control de fuente. Sin embargo, nuestra diferencia es que tratamos de limitar la cantidad de scripts que tenemos.
Para cualquier proyecto nuevo, hay un procedimiento establecido. Tenemos un script de creación de esquema en la versión 1, un script de creación de proc almacenado y posiblemente un script de creación de carga de datos inicial. Todos los procesos se guardan en un solo archivo, ciertamente masivo. Si utilizamos Enterprise Library, incluimos una copia del script de creación para el registro; si se trata de un proyecto ASP.NET que utiliza el marco de la aplicación ASP.NET (autenticación, personalización, etc.), también incluimos ese script. (Lo generamos a partir de las herramientas de Microsoft, luego lo ajustamos hasta que funcionó de manera replicable en diferentes sitios. No es divertido, pero es una inversión de tiempo valiosa).
Usamos la magia CTRL + F para encontrar el proceso que nos gusta. :) (Nos encantaría que SQL Management Studio tuviera navegación de código como lo hace VS. Suspiro!)
Para versiones posteriores, usualmente tenemos scripts upgradeSchema, upgradeProc y / o updateDate. Para las actualizaciones de esquema, ALTERAMOS las tablas tanto como sea posible, creando nuevas según sea necesario. Para actualizaciones de proceso, DROP y CREATE.
Una arruga aparece con este enfoque. Es fácil generar una base de datos, y es fácil obtener una nueva a la velocidad en la versión actual de DB. Sin embargo, se debe tener cuidado con la generación DAL (que actualmente, por lo general, hacemos con SubSonic), para garantizar que los cambios DB / schema / proc se sincronicen limpiamente con el código utilizado para acceder a ellos. Sin embargo, en nuestras rutas de compilación hay un archivo por lotes que genera SubSonic DAL, por lo que es nuestro SOP para verificar el código DAL, volver a ejecutar ese archivo por lotes y luego volver a revisarlo en cualquier momento que cambien el esquema y / o proc. (Esto, por supuesto, desencadena una compilación de origen, actualizando las dependencias compartidas a las DLL apropiadas ...)
Una cosa a tener en cuenta con las secuencias de comandos drop / create en SQL Server es que se perderán los permisos de nivel de objeto. Cambiamos nuestro estándar para usar scripts ALTER, que mantienen esos permisos.
Hay algunas otras advertencias, como el hecho de que al soltar un objeto se eliminan los registros de dependencia utilizados por sp_depends, y la creación del objeto solo crea las dependencias para ese objeto. Entonces, si suelta / crea una vista, sp_depends ya no sabrá de ningún objeto que haga referencia a esa vista.
Moraleja de la historia, use scripts ALTER.
Unir diferentes perspectivas desde mi experiencia. En el mundo de Oracle, todo fue gestionado por scripts "crear" DDL. Como ahockley mencionó, un script para cada objeto. Si el objeto necesita cambiar, su script DDL se modifica. Hay un script de envoltura que invoca todos los scripts de objetos para que pueda implementar la compilación de DB actual en el entorno que desee. Esto es para la creación del núcleo principal.
Obviamente, en una aplicación en vivo, cada vez que empuja una nueva construcción que requiere, digamos, una nueva columna, no va a soltar la tabla y crearla nueva. Harás un script ALTER y agregarás la columna. Entonces, cada vez que este tipo de cambio tiene que suceder, siempre hay dos cosas que hacer: 1) escribir el alter DDL y 2) actualizar el core create DDL para reflejar el cambio. Ambos entran en control de fuente, pero el script alter individual es más un cambio de punto momentáneo en el tiempo, ya que solo se usará para aplicar un delta.
También podría usar una herramienta como ERWin para actualizar el modelo y reenviar el DDL, pero la mayoría de los DBA que conozco no confían en una herramienta de modelado para generar el script exactamente de la manera que desean. También podría usar ERWin para realizar una ingeniería inversa de su secuencia de comandos DDL central en un modelo periódicamente, pero eso implica mucho esfuerzo para que se vea bien (cada vez que lo hace).
En el mundo de Microsoft, utilizamos una táctica similar, pero usamos el producto Red Gate para ayudar a administrar los scripts y deltas. Todavía pone los scripts en control de fuente. Todavía hay una secuencia de comandos por objeto (tabla, sproc, lo que sea). Al principio, algunos de los administradores de bases de datos preferían utilizar la GUI de SQL Server para administrar los objetos en lugar de usar scripts. Pero eso hizo que sea muy difícil administrar la empresa constantemente a medida que crecía.
Si el DDL está en control de fuente, es trivial utilizar cualquier herramienta de compilación (generalmente ant) para escribir un guión de implementación.
cree un "Proyecto de base de datos" en Visual Studio para escribir y administrar su código de SQL y mantener el proyecto bajo control de versión junto con el resto de su solución.