在查询中使用变量

时间:2016-03-23 15:59:53

标签: sql-server tsql

我正在尝试使用filestream创建一个文件组,如下所示:

declare @filepath varchar(800)
set @filepath = convert(sysname, SERVERPROPERTY('InstanceDefaultDataPath')) + N'MyDb_Files.ndf' 
print @filepath

alter database MyDb add file (name = 'MyDb_Files', filename = filepath) to filegroup MyDb_Files;
go

当我运行时,我收到错误:

The path 'filepath' cannot be used for FILESTREAM files.

但如果我更换

filename = filepath

通过

filename = "[Output I get from print @filepath]"

然后它工作正常......所以使用变量似乎是一个问题。

为什么?

更新

我尝试了以下内容:

declare @sql nvarchar(800)
set @sql = 
'
declare @filepath nvarchar(800)
set @filepath = concat(convert(sysname, SERVERPROPERTY("InstanceDefaultDataPath")), "MyDb.ndf")     
alter database MyDb add file (name = "MyDb_Files", filename = @filepath to filegroup MyDb_Files;        
'
exec (@sql)

但我一直收到错误: ' @ filepath'附近的语法不正确。

我现在做错了什么?

1 个答案:

答案 0 :(得分:0)

问题似乎是您尝试在不允许此类构造的DDL语句上使用参数(@filepath); DDL中的filename参数接受文字。 复制自(https://msdn.microsoft.com/en-us/library/bb522469.aspx):

<filespec>::= 
(
NAME = logical_file_name  
[ , NEWNAME = new_logical_name ] 
[ , FILENAME = {'os_file_name' | 'filestream_path' | 'memory_optimized_data_path' } ] 
[ , SIZE = size [ KB | MB | GB | TB ] ] 
[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ] 
[ , FILEGROWTH = growth_increment [ KB | MB | GB | TB| % ] ] 
[ , OFFLINE ]
) 

您必须使用动态SQL并确保自己免受SQLi攻击,例如:

declare @filepath nvarchar(800)
declare @sql nvarchar(max)
set @filepath = concat(convert(sysname, SERVERPROPERTY('InstanceDefaultDataPath')), 'MyDb.ndf')     
set @sql = N'
alter database MyDb add file (name = "MyDb_Files", filename = '''+ replace(@filepath, '''', '''''') + N''') to filegroup MyDb_Files;        
'
EXEC (@sql)

我在一篇旧博客文章https://blogs.msdn.microsoft.com/raulga/2007/01/04/dynamic-sql-sql-injection/中,在“当参数化不是一个选项时”一节下更多地谈论这个主题。希望你会发现这些信息很有用。