是:如何使用查询备份选定的存储过程
我想通过命令行(在SQL Server Management Studio中)备份200个存储过程中的10个。有一个简单的方法吗?
现在我正在使用Database-> Tasks-> Generate Scripts选项,它会引导我完成一系列对话框,我选择要导出的SP。我想让这个过程变得简单,所以我不必再重复一遍。
注意:通过导出我的意思是只在屏幕上打印它,这样我就可以将其复制并保存在文本文件中。
答案 0 :(得分:10)
如何使用INFORMATION_SCHEMA.Routines?
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
答案 1 :(得分:4)
您可以使用以下查询选择所需的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
答案 2 :(得分:4)
以下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
答案 3 :(得分:2)
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('')
单击结果窗格中的链接以查看整个脚本。
答案 4 :(得分:0)
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'
检查一下。这可能会对你有帮助。
答案 5 :(得分:0)
不是SQL方式,但我认为您可以使用autoit或{{3自动化您的数据库 - &gt;任务 - &gt;生成脚本选项/ ...更多步骤或者其他一些GUI测试工具。
我尝试了一些Sikuli用于网络,但对我来说这并不是100%可靠。
AutoIt v3是一款免费的类似BASIC的脚本语言 自动化Windows GUI和常规脚本。
答案 6 :(得分:0)
我编辑了MyItchyChin的脚本,因为我发现了它的一些缺陷。当@part&lt;时,它会无限循环。 0并且无法正确打印关闭过程代码的“END”关键字(“创建过程...作为开始...... 结束”)。我也做了其他一些小改动。我的问题现在解决了!非常感谢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
答案 7 :(得分:0)
我创建了以下过程,通过所有SP和视图,特别是DB(可以扩展到Functions,...),并将每个代码脚本逐个存储到TXT文件中。在MS SQL 2008 R2和2014上测试
第一部分将SP和Views的所有脚本插入Temp表。然后使用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