2009-02-20 28 views
8

Me gustaría guardar mis procedimientos almacenados de MS SQL Server 2005 en archivos .sql automáticamente (preferiría una herramienta a la que pueda llamar mediante .bat) así que no tengo que hacer clic cada sproc individual manualmente y guárdalo.cómo guardar los procedimientos SQL almacenados en archivos .sql por lote

Ya he encontrado SMOscript de devio IT, pero reúne todas las tablas y sproc, lo que lleva algún tiempo. ¿Hay alguna herramienta similar donde pueda definir qué sproc (s) exportar? También me falta la cláusula USE que SMOScript no agrega al archivo exportado en contraste con la exportación manual como sproc de script para CREATE.

mejores deseos Sean

Respuesta

5

Crear archivo por lotes con la escritura (lo siento sobre el formato, pero en realidad debería estar en línea para ejecutar por lotes):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -o "sp_list.txt" 
for /f %%a in (sp_list.txt) do osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -o "%%a.sql" 

el nombre de "run.bat". Ahora, para ejecutar por lotes params uso:
run.bat [nombre de usuario] [contraseña] [servidor] [base de datos]
de ejemplo:
run.bat sa pwd111 localhost \ SQLEXPRESS maestro
nombres de los procedimientos almacenados primero de todo será almacenado en el archivo sp_list.txt, luego uno por uno en archivos de script separados. El único problema - la última línea de cada script con el recuento de resultado - Estoy trabajando en él :)

editado: error en la consulta fija

Extracción 'filas afectadas' línea
Ok, ahora tenemos que crear un lote más:

type %1 | findstr /V /i %2 > xxxtmpfile 
copy xxxtmpfile %1 /y /v 
del xxxtmpfile 

Llámalo "line_del.bat". Ver, el primer parámetro es archivo para procesar, 2da cadena para buscar líneas para eliminar.Ahora modifique el lote principal (de nuevo, lo siento sobre el formato):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -o "sp_list.txt" 
call line_del sp_list.txt "rows affected" 
call line_del sp_list.txt "row affected" 
for /f %%a in (sp_list.txt) do osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -o "%%a.sql" 
for /f %%a in (sp_list.txt) do call line_del %%a.sql "rows affected" 
for /f %%a in (sp_list.txt) do call line_del %%a.sql "row affected" 

Ver artículos relacionados:
Simple programming commands in a batch environment
osql Utility
MSSQL: How do you script Stored Procedure creation with code?
Delete certain lines in a txt file via a batch file

:) se puede notar que dos últimos son de ¡ASI QUE!

+0

¡Muchas gracias! He intentado un poco, pero tengo algunos problemas con la autenticación (osql no puedo conectar). Lo intentaré de nuevo los próximos días ... mis mejores deseos – seansilver

+1

¿No sería así para los procs grandes? Cuando corro: SELECCIONAR ROUTINE_NAME, max (len (ROUTINE_DEFINITION)) FROM INFORMATION_SCHEMA.Routines group by ROUTINE_NAME ordenar por 2 desc; Obtengo muchos procs de 4000 caracteres. Seguro que necesita salir de sys.comments para obtener los datos correctos. – jcollum

+0

Vaya, eso debería ser syscomments en el comentario anterior. – jcollum

2

Hay una alternativa en SQL Server Management Studio, secuencias de comandos de la base de datos ...

expandir la vista Explorador de objetos para encontrar la base de datos, haga clic derecho y seleccionar "Tareas: Generar Secuencias de comandos "

Desde allí se puede ejecutar un script de todos los objetos, solo los procedimientos almacenados, de cualquier elemento intermedio. Hay bastantes opciones en una página, aunque la principal que cambio es: - "Incluir SI NO EXISTE"

Al hacer que esta opción sea "FALSA", acaba de obtener una lista completa de instrucciones CREATE.

Puede elegir guiar los objetos a una nueva ventana de consulta o un archivo.

+0

Gracias por la pista, por desgracia, esto tiene algunas desventajas para mí - Tengo que ir a través de todos los pasos cada vez con la mano (no auto/lote) - todos los procedimientos almacenados seleccionados se guardan en una .sql archivo - no hay comentarios guardados – seansilver

0

He usado sqlcmd y -E en lugar de usuario, pase. Esto funciona bien hasta el momento, solo los procedimientos almacenados más de 4000 caracteres tendrán un salto de línea

sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt" 
call line_del sp_list.txt "rows affected" 
call line_del sp_list.txt "row affected" 
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql" 
for /f %%a in (sp_list.txt) do call line_del %%a.sql "rows affected" 
for /f %%a in (sp_list.txt) do call line_del %%a.sql "row affected" 

mejores deseos Sean

0

agregué SET NOCOUNT ON para eliminar la necesidad de line_del.bat. También reemplazó syscomments con sys.sql_modules (SQL 2005). También podría haber usado la función OBJECT_DEFINITION pero fue más lenta que sys.sql_modules.

sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt" for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT definition from sys.sql_modules WHERE object_id = OBJECT_ID('%%a')" -o "%%a.sql" 
+0

No es una respuesta independiente, debe ser un comentario sobre la respuesta de la que está hablando. – jcollum

1

Adición del SET NOCOUNT ON eliminó de hecho la necesidad de que el line_del.bat, pero reemplazando syscomments con sys.sql_modules resultó en cada procedimiento almacenado que se trunca a 258 caracteres. Así que para los mejores resultados el código que utilicé fue:

sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt" 
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql" 

que funcionaba, y no era necesario el uso de la line_del.bat. Lo que no me dieron cuando hice la exportación manual utilizando el Asistente SSMS (Tareas/generar scripts/procedimientos almacenados/Seleccionar todo) fue el:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

al comienzo de cada .sql, y el comando de arrastre GO también . No es increíblemente importante, pero hay que tener en cuenta. ¡Gracias a Max Gontar, Seansilver y Lee por sus contribuciones! Ahora puedo automatizar la copia de seguridad de los procedimientos almacenados en la base de datos y aplicar el control de versiones.

0

Gracias a todos los anteriores por ayuda y dejando esto aquí para que otros noobs sqlcmd como yo podamos encontrar. Funciona en el servidor sql 2005. objectName es un procedimiento, ver el nombre etc.

:reset 

-- :setvar ObjectName "objectName" -- works 
:setvar ObjectName objectName -- works too 
declare @sql varchar(max); 
set @sql = 'select text from dbo.syscomments where id = object_id(upper("' + '$(ObjectName)' + '"))'; 
-- exec sp_helptext $(ObjectName) -- quick n easy but gets chopped to 256 width 
/* 4000 byte limit 
set @sql = 
    'select view_definition 
    from information_schema.views 
    where upper(table_name) = upper("' + '$(ObjectName)' + '")'; 
*/ 
:out $(ObjectName).sql 

exec(@sql) 
go 

:out stdout 
Cuestiones relacionadas