我正在尝试使用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'附近的语法不正确。
我现在做错了什么?
答案 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/中,在“当参数化不是一个选项时”一节下更多地谈论这个主题。希望你会发现这些信息很有用。