我想在一个应用程序中创建一个数据库,在运行时提供一个名称。
当前的解决方案是:
create database [USER_PROVIDED_NAME] ...
该解决方案的问题是,用户提供的名称可能包含[或],导致语法错误(并可能导致SQL注入)。
有没有一种方法可以安全地做到这一点,而不限制可能的数据库名称?
可以使用QUOTENAME
函数:
select quotename('foo[bar]baz'); -- [foo[bar]]baz]
create database [foo[bar]]baz];
话虽如此,我宁愿使用允许字符的白名单来拒绝这些名称。
如果在您的应用程序中控制了这一点,那么您可以对右括号(]
)进行分隔、标识和转义。左括号([
)不需要转义:
CREATE DATABASE [This is a [really]] bad idea for a [database]] name];
或者,如果您想在SQL层处理这个问题,并且数据库名称来自应用程序,您可以使用动态SQL和QUOTENAME
:
DECLARE @DatabaseName sysname = N'This is a [really] bad idea for a [database] name'; --This is your parameter
DECLARE @SQL nvarchar(MAX) = N'CREATE DATABASE ' + QUOTENAME(@DatabaseName) + N';';
EXEC sys.sp_executesql @SQL;
您可以在这里使用ANSI转义双引号:
CREATE DATABASE "Name with [stuff]";