目标:在Master数据库中创建一用户数据库备份过程
做法:在企业管理器中生成已测试通过的该存储过程,保存到txt文件中。在delphi中读出该过程代码,然后提交数据库服务器执行。报错误!!!好象数据库服务器把该代码中的命令“单独执行了”!!!实际上,该代码在查询分析器中可以成功创建存储过程!!高手出招。谢谢!!
做法:在企业管理器中生成已测试通过的该存储过程,保存到txt文件中。在delphi中读出该过程代码,然后提交数据库服务器执行。报错误!!!好象数据库服务器把该代码中的命令“单独执行了”!!!实际上,该代码在查询分析器中可以成功创建存储过程!!高手出招。谢谢!!
var
MySourStr:Tstrings;
j:integer;
begin
MySourStr := TStringList.Create;
//检测过程是否存在
with query1 do
begin
close;
sql.Clear;
sql.Add('select id,name from dbo.sysobjects');
sql.Add(' where (id=object_id(N''[dbo].[Pub_RestoreDB]'')) and (OBJECTPROPERTY(id, N''IsProcedure'')=1)');
Prepare;
Open;
end;
//不存在,创建
if query1.isempty then
begin
if FileExists('我的过程.txt') then
begin
MySourStr.LoadFromFile('我的过程.txt');
if MySourStr.Count=0 then exit;
with query1 do
begin
close;
sql.Clear;
j:=0;
while j<=MySourStr.Count-1 do
begin
sql.Add(MySourStr[j]);
j:=j+1;
end;
Prepare;
Execsql;
end;
end;
end;
end;
问题是,数据库服务器好象把该代码集中的某些命令“单独执行了”!居然报告某个变量不存在...而不是作为创建存储过程处理的!下面是我的创建存储过程代码(保存在文本文件中):if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Pub_RestoreDB]') and OBJECTPROPERTY(id, N'IsProcedure')=1)
drop procedure [dbo].[Pub_RestoreDB]
GOSET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
CREATE proc Pub_RestoreDB
@bkfile nvarchar(1000),
@dbname sysname='',
@dbpath nvarchar(260)='',
@retype nvarchar(10)='DB',
@filenumber int=1,
@overexist bit=1,
@killuser bit=1,
@password nvarchar(20)=''
as
declare @sql varchar(8000)
--得到恢复后的数据库名
if isnull(@dbname,'')=''
select @sql=reverse(@bkfile)
,@sql=case when charindex('.',@sql)=0 then @sql
else substring(@sql,charindex('.',@sql)+1,1000) end
,@sql=case when charindex('\',@sql)=0 then @sql
else left(@sql,charindex('\',@sql)-1) end
,@dbname=reverse(@sql)
--得到恢复后的数据库存放目录
if isnull(@dbpath,'')=''
begin
select @dbpath=rtrim(reverse(filename)) from master..sysfiles where name='master'
select @dbpath=reverse(substring(@dbpath,charindex('\',@dbpath),4000))
end
--生成数据库恢复语句
set @sql='restore '+case @retype when 'LOG' then 'log ' else 'database ' end+@dbname
+' from disk='''+@bkfile+''''
+' with file='+cast(@filenumber as varchar)
+case when @overexist=1 and @retype in('DB','DBNOR') then ',replace' else '' end
+case @retype when 'DBNOR' then ',NORECOVERY' else ',RECOVERY' end
+case isnull(@password,'') when '' then '' else ',PASSWORD='''+@password+'''' end
--添加移动逻辑文件的处理
if @retype='DB' or @retype='DBNOR'
begin
--从备份文件中获取逻辑文件名
declare @lfn nvarchar(128),@tp char(1),@i int,@s varchar(1000)
--创建临时表,保存获取的信息
create table #tb(ln nvarchar(128),pn nvarchar(260),tp char(1),fgn nvarchar(128) null ,sz numeric(20,0),Msz numeric(20,0))
--从备份文件中获取信息
set @s='restore filelistonly from disk='''+@bkfile+''''
++case isnull(@password,'') when '' then '' else ' with PASSWORD='''+@password+'''' end
insert into #tb exec(@s)
declare #f cursor for select ln,tp from #tb
open #f
fetch next from #f into @lfn,@tp
set @i=0
while @@fetch_status=0
begin
select @sql=@sql+',move '''+@lfn+''' to '''+@dbpath+@dbname+cast(@i as varchar)
+case @tp when 'D' then '.mdf''' else '.ldf''' end
,@i=@i+1
fetch next from #f into @lfn,@tp
end
close #f
deallocate #f
end
--关闭用户进程处理
if @overexist=1 and @killuser=1
begin
declare hCForEach cursor for
select s='kill '+cast(spid as varchar) from master..sysprocesses
where dbid=db_id(@dbname)
exec sp_msforeach_worker '?'
end
--恢复数据库
exec(@sql)
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
2)把文件中的语句都load到query里,所有的 " ' "都要处理的吧?就像楼上所说的,你把写入到query里的内容读到Memo里看一下就知道了。
如果一定要用保存的txt文件执行创建过程,可以考虑用Osql或isql工具辅助执行
最后的
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
也不需要!!
实际上只要把你在过程里(已建好的)看见的内容复制到文本文件中就可以啦!!结帖!!!
结帖!!!