2013-11-28 37 views
1

我有以下存储过程,它以每个输入完整文件路径字符串的字节为单位返回文件大小。使用调用一个存储过程调用另一个TSQL更新表

我想编写另一个包装存储过程或函数来更新一个有两列的表。 Full_Path列(下面的存储过程的输入)和列大小(应由下面的过程的输出更新)。基本上我想使用下面的过程更新每个文件的大小列(在完整路径列中指定)。

我不知道该怎么做。请指教。

Create proc sp_get_file_size (@fileName varchar(200)) 
as 

begin 
declare @ntcmd varchar(200) 
declare @detailLine varchar(200) 
declare @pos1 int 
declare @pos2 int 
declare @size int 

set nocount on 

Create table #res (line varchar(400)) 
set @ntcmd = 'dir /-C ' + @fileName 
insert #res exec xp_CmdShell @ntcmd 
select @detailLine = line 
    from #res where rtrim(ltrim(line)) like '%bytes' 

-- if detail Line is null - return -1 
if isnull (@detailLine ,'*') = '*' return -1 

-- get position of words bytes and File(s) 
set @pos1 = charindex ('bytes' ,lower(@detailLine)) 
set @pos2 = charindex ('(s)' , lower(@detailLine)) 

-- extract the size value from the details Line 
set @size = convert (int, rtrim(ltrim( 
         substring (@detailLine , @pos2+3,@pos1 - @pos2 - 4)))) 
return (@size) 
set nocount off 
end 
go 
+1

注意:你不应该**为存储过程使用'sp_'前缀。微软已经保留了这个前缀以供自己使用(参见*命名存储过程*)](http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx),以及你将来有可能冒着名字冲突的风险。 [这对你的存储过程性能也是不利的](http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix)。最好只是简单地避免使用'sp_'并将其他内容用作前缀 - 或者根本没有前缀! –

回答

1

将您的存储过程重写为标量用过的函数,该函数返回大小。然后,你不需要第二个存储过程,一个更新语句将这样的伎俩:

UPDATE MyTable SET Size = fn_get_file_size(Full_Path) 

(注:你需要,因为临时表使用表变量来代替临时表#res不准里面的UDFs)

+0

不错的答案Vash! – user2705620

+0

注意SP中的exec xp_CmdShell @ntcmd。我不能用我认为的函数来调用它。我得到的错误是我无法在函数中使用insert exec。任何解决方法? – user2965499

+0

我相信扩展存储过程可以从UDF调用,从来没有尝试过,但它应该是可能的。如果不是 - 你将不得不求助于通过表循环(CURSOR哦),并单独运行每个记录的SP。或者通过多次调用SP来构建一个动态SQL,并一次执行它 –

相关问题