экспорт хранимых процедур с помощью SQL скрипта
Was: как создать резервную копию выбранной хранимой процедуры с помощью query
Я хотел бы создать резервную копию 10 из 200 процедур хранения через командную строку (в SQL Server Management Studio). Существует ли простой способ сделать это?
прямо сейчас я использую опцию Database - >Tasks - >Generate Scripts, которая проходит через ряд диалоговых окон, где я выбираю SP, который я хочу экспортировать. Я хотел бы сделать этот процесс легким, поэтому мне не нужно делать все это снова снова.
Примечание: под экспортом я имею в виду просто распечатать его на экране, чтобы я мог скопировать его и сохранить в текстовом файле.
8 ответов
Как насчет использования INFORMATION_SCHEMA.Рутины ?
DECLARE MY_CURSOR Cursor
FOR
SELECT r.Routine_Definition
FROM INFORMATION_SCHEMA.Routines r
OPEN MY_CURSOR
DECLARE @sproc VARCHAR(MAX)
FETCH NEXT FROM MY_CURSOR INTO @sproc
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
PRINT @sproc
FETCH NEXT FROM MY_CURSOR INTO @sproc
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
GO
редактировать
похоже, вам может понадобиться что-то вроде этого, чтобы включить дату и определение LAST_ALTERED в результирующий набор.
SELECT
r.LAST_ALTERED,
r.ROUTINE_NAME,
r.Routine_Definition
FROM INFORMATION_SCHEMA.Routines r
вы можете выбрать SP, которые вы хотите со следующим запросом:
SELECT obj.Name as SPName,
modu.definition as SPDefinition,
obj.create_date as SPCreationDate
FROM sys.sql_modules modu
INNER JOIN sys.objects obj
ON modu.object_id = obj.object_id
WHERE obj.type = 'P' AND obj.Name IN ('sp1','sp2', ect)
см. также:http://www.sqlservercurry.com/2009/03/list-all-stored-procedures-of-database.html и http://www.sqlservercurry.com/2007/12/redirect-select-query-output-to-text.html
следующий SQL должен делать то, что вы хотите.
SET NOCOUNT ON
DECLARE @procs AS TABLE( object_id INT
, definition NVARCHAR(MAX)
, uses_ansi_nulls BIT
, uses_quoted_identifier BIT
)
INSERT INTO @procs
SELECT m.object_id
, m.definition
, m.uses_ansi_nulls
, m.uses_quoted_identifier
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
ON m.object_id = o.object_id
WHERE o.type = 'P'
--Change this part to suit your needs...
AND o.name IN ('sproc1'
,'sproc2'
,'sproc3'
)
--Optionally filter by date?
--AND o.create_date >= '02/01/2012'
DECLARE @endStmt NCHAR(6)
, @object_id INT
, @definition NVARCHAR(MAX)
, @uses_ansi_nulls BIT
, @uses_quoted_identifier BIT
SELECT @object_id = MIN(object_id)
, @endStmt = CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
FROM @procs
WHILE ISNULL(@object_id,0) > 0
BEGIN
SELECT @definition = definition
, @uses_ansi_nulls = uses_ansi_nulls
, @uses_quoted_identifier = uses_quoted_identifier
FROM @procs
IF @uses_ansi_nulls = 1
PRINT 'SET ANSI_NULLS ON' + @endStmt
ELSE
PRINT 'SET ANSI_NULLS OFF' + @endStmt
IF @uses_quoted_identifier = 1
PRINT 'SET QUOTED_IDENTIFIER ON' + @endStmt
ELSE
PRINT 'SET QUOTED_IDENTIFIER OFF' + @endStmt
IF LEN(@definition) <= 4000
PRINT @definition
ELSE
BEGIN
DECLARE @crlf VARCHAR(2), @len BIGINT, @offset BIGINT, @part BIGINT
SELECT @crlf = CHAR(13)+CHAR(10)
, @len = LEN(@definition)
, @offset = 1
, @part = CHARINDEX(@crlf,@definition)-1
WHILE @offset <= @len
BEGIN
PRINT SUBSTRING(@definition,@offset,@part)
SET @offset = @offset + @part + LEN(@crlf)
SET @part = CHARINDEX(@crlf,@definition,@offset)-@offset
END
END
PRINT @endStmt
SELECT @object_id = MIN(object_id)
FROM @procs
WHERE object_id > @object_id
END
Если вы сохраните вышеуказанный SQL как файл с именем BackUpSprocs.SQL затем вы можете запустить команду, подобную следующей, чтобы получить вывод в файл.
SQLCMD -E -S SQLSERVER_NAME -d DATABASE_NAME -i BackUpSprocs.SQL -o Sprocs.txt
declare @S nvarchar(max)
set @S = N''
select @S = @S + [definition] +
nchar(13) + nchar(10) +
N'GO' +
nchar(13) + nchar(10)
from sys.sql_modules as m
inner join sys.objects as o
on m.object_id = o.object_id
where o.create_date > '20120101' and
o.name in ('Proc1', 'Proc2', 'ProcN')
select @S
for xml path('')
нажмите на ссылку в области результатов, чтобы просмотреть весь сценарий.
SELECT SO.Name as Name,
SM.definition as SPDefinition,
obj.create_date as CreationDate
FROM sys.sql_modules SM
INNER JOIN sys.objects SO
ON SM.object_id = SO.object_id
WHERE SO.type = 'P' AND SO.create_date >= '01-01-2012'
зацени. Это может вам помочь.
Не путь SQL, но я думаю, что вы могли бы автоматизировать базу данных - >задачи - >создать сценарий вариант/...Больше Шагов С помощью autoit или Sikuli или, может быть, какой-то другой инструмент тестирования GUI.
Я попробовал немного Sikuli для сети, и это не было 100% надежным для меня.
AutoIt v3-это бесплатный базовый язык сценариев, предназначенный для автоматизация Windows и общего сценария.
я отредактировал сценарий MyItchyChin, так как нашел в нем некоторые недостатки. Это будет цикл неопределенно, когда @part конец"). Я внес и другие незначительные изменения. Мои проблемы теперь решены! Большое спасибо MyItchyChin за первоначальный сценарий.
Obs: я использую этот скрипт в SQL Server 2008 R2. Скрипт также может использоваться для функций скрипта.
SET NOCOUNT ON
DECLARE @procs AS TABLE( nome varchar(200),object_id INT
, definition NVARCHAR(MAX)
, uses_ansi_nulls BIT
, uses_quoted_identifier BIT
)
INSERT INTO @procs
SELECT o.name
,m.object_id
, m.definition
, m.uses_ansi_nulls
, m.uses_quoted_identifier
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
ON m.object_id = o.object_id
WHERE 1=1
--and o.type = 'P'
AND o.name IN ('proc1')
DECLARE @endStmt NCHAR(6)
, @object_id INT
, @definition NVARCHAR(MAX)
, @uses_ansi_nulls BIT
, @uses_quoted_identifier BIT
DECLARE @crlf VARCHAR(2), @len BIGINT, @offset BIGINT, @part BIGINT
SELECT @object_id = MIN(object_id)
, @endStmt = CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
FROM @procs
declare c cursor for SELECT definition
, uses_ansi_nulls
, uses_quoted_identifier
FROM @procs
order by nome asc
open c
fetch next from c into @definition,@uses_ansi_nulls,@uses_quoted_identifier
while @@fetch_status<>-1
begin
IF @uses_ansi_nulls = 1
PRINT 'SET ANSI_NULLS ON' + @endStmt;
ELSE
PRINT 'SET ANSI_NULLS OFF' + @endStmt;
IF @uses_quoted_identifier = 1
PRINT 'SET QUOTED_IDENTIFIER ON' + @endStmt;
ELSE
PRINT 'SET QUOTED_IDENTIFIER OFF' + @endStmt;
--PRINT @definition;
IF LEN(@definition) <= 4000
PRINT @definition
ELSE
BEGIN
SELECT @crlf = CHAR(13)+CHAR(10)
, @len = LEN(@definition)
, @offset = 1
, @part = CHARINDEX(@crlf,@definition)-1
WHILE @offset <= @len AND @part>=0
BEGIN
--PRINT @offset
--PRINT @part
--PRINT LEN(@crlf)
--PRINT @len
PRINT SUBSTRING(@definition,@offset,@part)
SET @offset = @offset + @part + LEN(@crlf)
SET @part = CHARINDEX(@crlf,@definition,@offset)-@offset
--PRINT @offset
--PRINT @part
--PRINT @len
IF @part < 0
PRINT SUBSTRING(@definition,@offset,100)
END
END
PRINT @endStmt;
fetch next from c into @definition,@uses_ansi_nulls,@uses_quoted_identifier
end
close c
deallocate c
Я создаю следующую процедуру, которая проходит через все SP и представления в частности DB (можно расширить до функций, ...) и храните каждый сценарий кода один за другим в txt-файлы. Протестировано на MS SQL 2008 R2 и 2014
первая часть вставка всех скриптов SP и представлений во временную таблицу. Затем позже с помощью утилиты BCP. Если вы хотите, вы можете использовать для экспорта пакета SSIS, а не SP, как я сделал в этом примере.
DECLARE @File_name AS VARCHAR(255)
,@Folder_path AS VARCHAR(255)
,@File_Path_Name AS VARCHAR(255)
,@CMD AS VARCHAR(8000)
IF OBJECT_ID('tempdb..#TEMP_AA') IS NOT NULL DROP TABLE #TEMP_AA;
SELECT
T1.NAME AS ObjectName
,T1.type AS ObjectType
,STUFF(((SELECT ' ' + T.[TEXT]
FROM (SELECT SC.[id],SC.colid,SC.[TEXT]
FROM SYSCOMMENTS sc
) AS T
WHERE T.[id] = T1.[id]
ORDER BY T.colid
FOR XML PATH(''),TYPE
).value('.[1]', 'NVARCHAR(MAX)')
), 1, 1, '')
AS ObjectText
INTO #TEMP_AA
FROM SYSOBJECTS AS T1
WHERE 1=1
AND T1.type IN ('P', 'V') /* Procedures and Views*/
AND NOT T1.[name] LIKE 'dt_%'
цикл проходит через временную таблицу, создавая имя файла с Префикс P_ или V_ и с суффиксом как дата в формате YYYYMMDD:
-- Exporting Scripts one by one into TXT files
WHILE (SELECT TOP 1 objectName FROM #TEMP_AA) IS NOT NULL
BEGIN
SELECT TOP 1
@File_name = RTRIM(LTRIM(ObjectType)) + '_' + ObjectName +'_' + REPLACE(CAST(CAST(GETDATE()AS DATE) AS VARCHAR),'-','')
FROM #TEMP_AA;
IF OBJECT_ID('tempdb..##TEMP_BB') IS NOT NULL DROP TABLE ##TEMP_BB;
CREATE TABLE ##TEMP_BB (ObjectText VARCHAR(MAX));
INSERT INTO ##TEMP_BB
SELECT TOP 1 ObjectText
FROM #TEMP_AA;
--'Setting File name'
SET @Folder_Path = 'C:\AAAA\'
SET @File_Path_Name = @Folder_Path + @File_name + '.txt'
SET @CMD ='BCP ##TEMP_BB OUT "'+@File_Path_Name+'" -T -c -t "Your Server"'
-- 'Output via BCP into TXT file'
EXEC xp_cmdshell @CMD;
--Delete Line From temp which has been procese already
WITH CTE AS (SELECT TOP 1 * FROM #TEMP_AA)
DELETE FROM CTE;
END