无法使用变量将参数传递给存储过程

时间:2017-01-13 18:33:59

标签: sql-server stored-procedures exec

我想连接一个字符串并传递给一个过程...我可以让它在第一个硬编码的例子上工作,但我需要传递一个动态文件名 - 所以需要让以下一个失败工作...

这种硬编码工作正常:

exec master.dbo.sp_getfiledetails_CC 'c:\temp\test file.xml'
    , @filedate = @FileDateTime OUTPUT

这不是:

DECLARE @CCTMP as varchar(max)
set @cctmp = 'master.dbo.sp_getfiledetails_CC ''c:\temp\text file.xml''
    , @filedate = @FileDateTime OUTPUT'
exec @cctmp

这不是:

DECLARE @CCTMP as varchar(max)
DECLARE @FileName as varchar(max)
set @filename = 'c:\temp\text file.xml'
set @cctmp = 'master.dbo.sp_getfiledetails_CC ' + @filename +'
    , @filedate = @FileDateTime OUTPUT'
exec @cctmp

这两点都没有:

DECLARE @FileName as varchar(max)
set @filename = 'c:\temp\text file.xml'
exec master.dbo.sp_getfiledetails_CC ' + @filename +'
    , @filedate = @FileDateTime OUTPUT'

这是程序:

[DBO]。[sp_getfiledetails_CC]

    (
        @filename NVARCHAR(255) = NULL --(full path)
        ,@filedate DATETIME OUTPUT
    )

AS
DECLARE @fileobj INT , @fsobj INT
DECLARE @exists INT, @error INT 
DECLARE @src VARCHAR(255), @desc VARCHAR(255)


--create FileSystem Object
EXEC @error = sp_OACreate 'Scripting.FileSystemObject', @fsobj OUT
IF @error <> 0
BEGIN
EXEC sp_OAGetErrorInfo @fsobj, @src OUT, @desc OUT 
SELECT error=CONVERT(varbinary(4),@error), Source=@src, Description=@desc
RETURN 2
END

--check if specified file exists
EXEC @error = sp_OAMethod @fsobj, 'FileExists', @exists OUT, @filename

IF @exists = 0
BEGIN
--RAISERROR 22004 'The system cannot find the file specified.'
RETURN 2
END

--Create file object that points to specified file
EXEC @error = sp_OAMethod @fsobj, 'GetFile' , @fileobj OUTPUT, @filename
IF @error <> 0
BEGIN
EXEC sp_OAGetErrorInfo @fsobj
RETURN 2
END

--Declare variables holding properties of file
DECLARE @Attributes TINYINT, 
@DateCreated DATETIME, 
@DateLastAccessed DATETIME,
@DateLastModified DATETIME,
@Drive VARCHAR(1),
@Name NVARCHAR(255),
@ParentFolder NVARCHAR(255),
@Path NVARCHAR(255),
@ShortPath NVARCHAR(255),
@Size INT,
@Type NVARCHAR(255)

--Get properties of fileobject
EXEC sp_OAGetProperty @fileobj, 'Attributes', @Attributes OUT
EXEC sp_OAGetProperty @fileobj, 'DateCreated', @DateCreated OUT
EXEC sp_OAGetProperty @fileobj, 'DateLastAccessed', @DateLastAccessed OUT 
EXEC sp_OAGetProperty @fileobj, 'DateLastModified', @DateLastModified OUT 
EXEC sp_OAGetProperty @fileobj, 'Drive', @Drive OUT
EXEC sp_OAGetProperty @fileobj, 'Name', @Name OUT
EXEC sp_OAGetProperty @fileobj, 'ParentFolder', @ParentFolder OUT
EXEC sp_OAGetProperty @fileobj, 'Path', @Path OUT
EXEC sp_OAGetProperty @fileobj, 'ShortPath', @ShortPath OUT
EXEC sp_OAGetProperty @fileobj, 'Size', @Size OUT
EXEC sp_OAGetProperty @fileobj, 'Type', @Type OUT

--destroy File Object
EXEC @error = sp_OADestroy @fileobj
IF @error <> 0
BEGIN
EXEC sp_OAGetErrorInfo @fileobj
RETURN
END

--destroy FileSystem Object
EXEC @error = sp_OADestroy @fsobj
IF @error <> 0
BEGIN
EXEC sp_OAGetErrorInfo @fsobj
RETURN 2
END


--return results
SELECT NULL AS [Alternate Name], 
@Size AS [Size], 
CONVERT(varchar, @DateCreated, 112) AS [Creation Date], 
REPLACE(CONVERT(varchar, @DateCreated, 108), ':', '') AS [Creation Time], 
CONVERT(varchar, @DateLastModified, 112) AS [Last Written Date], 
REPLACE(CONVERT(varchar, @DateLastModified, 108), ':', '') AS [Last Written Time], 
CONVERT(varchar, @DateLastAccessed, 112) AS [Last Accessed Date], 
REPLACE(CONVERT(varchar, @DateLastAccessed, 108), ':', '') AS [Last Accessed Time], 
@Attributes AS [Attributes]

--SET @filedate = REPLACE(CONVERT(varchar, @DateLastModified, 108), ':', '')
set @filedate = convert(datetime, CONVERT(float,@DateLastModified))

2 个答案:

答案 0 :(得分:0)

我认为这可以回答你的问题。

传递参数时,这不起作用:

DECLARE @CCTMP as varchar(max)
set @cctmp = 'master.dbo.sp_who 1'
exec @cctmp

但如果你在():

中包装varable,它会起作用
DECLARE @CCTMP as varchar(max)
set @cctmp = 'master.dbo.sp_who 1'
exec (@cctmp)

所以你的例子应该是这样的:

declare @CCTMP as varchar(max)

set @cctmp = 'declare @FileDateTime datetime
exec master.dbo.sp_getfiledetails_CC ''c:\temp\text file.xml''
   , @filedate = @FileDateTime OUTPUT
select @FileDateTime'

-- create table to handle output of query
declare @output table (output varchar(max))
insert @output exec (@cctmp)

-- then you can pull your variable from @output
select * from @output

答案 1 :(得分:0)

不确定为什么使用动态sql。它只是增加了一层你不需要的混乱。

您要做的是参数的全部要点。这就像这一样简单。

DECLARE @FileName as varchar(max)
set @filename = 'c:\temp\text file.xml'

declare @FileDateTime datetime

exec master.dbo.sp_getfiledetails_CC @filename, @FileDateTime OUTPUT

FWIW,不确定为什么要在master中创建过程。无论哪种方式,MS都为系统过程保留sp_前缀,添加自己的前缀是有风险的。您可以在此处详细了解为何应避免使用该前缀。 http://sqlperformance.com/2012/10/t-sql-queries/sp_prefix