Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么要使用QUOTENAME函数?_Sql Server_Tsql - Fatal编程技术网

Sql server 为什么要使用QUOTENAME函数?

Sql server 为什么要使用QUOTENAME函数?,sql-server,tsql,Sql Server,Tsql,我熟悉函数。但我不明白我能用什么?为什么它被如此广泛地使用 select quotename('[abc]') -- '[[abc]]]' select quotename('abc') -- '[abc]' select '[' + 'abc' +']' -- why it is not so good as previous? 假设计划定期运行以下脚本来清理模式中的表,而不是dbo模式 DECLARE @TABLE_SCHEMA SYSNAME, @TABLE_NAME

我熟悉函数。但我不明白我能用什么?为什么它被如此广泛地使用

select quotename('[abc]') -- '[[abc]]]'
select quotename('abc') -- '[abc]'
select '[' + 'abc' +']'  -- why it is not so good as previous?

假设计划定期运行以下脚本来清理模式中的表,而不是
dbo
模式

DECLARE @TABLE_SCHEMA SYSNAME,
        @TABLE_NAME   SYSNAME
DECLARE @C1 AS CURSOR;

SET @C1 = CURSOR FAST_FORWARD
FOR SELECT TABLE_SCHEMA,
           TABLE_NAME
    FROM   INFORMATION_SCHEMA.TABLES
    WHERE  TABLE_SCHEMA <> 'dbo'

OPEN @C1;

FETCH NEXT FROM @C1 INTO @TABLE_SCHEMA, @TABLE_NAME;

WHILE @@FETCH_STATUS = 0
  BEGIN
      PRINT 'DROP TABLE [' + @TABLE_SCHEMA + '].[' + @TABLE_NAME + ']';

      EXEC ('DROP TABLE [' + @TABLE_SCHEMA + '].[' + @TABLE_NAME + ']');

      FETCH NEXT FROM @C1 INTO @TABLE_SCHEMA, @TABLE_NAME;
  END 
现在创建以下内容并重试

CREATE TABLE foo.[[abc]]](x int)
脚本失败并出现错误

DROP TABLE [foo].[[abc]]
Msg 105, Level 15, State 1, Line 6
Unclosed quotation mark after the character string '[abc]'.
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near '[abc]'.
因此,不使用
QUOTENAME
导致脚本失败。闭合支架没有通过将其对折正确脱离。正确的语法应该是

DROP TABLE [foo].[[abc]]]
更糟糕的是,恶意开发人员已经知道了脚本的存在。它们在脚本计划运行之前执行以下操作

CREATE TABLE [User supplied name]]; 
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin';  --]
(
x int
)
现在,最终执行的脚本是

DROP TABLE [foo].[User supplied name]; 
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin';  --]

]
被解释为关闭对象名称,其余部分作为新语句。第一条语句返回一条错误消息,但不是终止一条语句的作用域,第二条语句仍在执行。通过不使用
QUOTENAME
您已经打开了SQL注入的大门,并且开发人员已经成功地提升了他们的权限

QUOTENAME
可以在生成动态SQL语句时使用。它确实会将您的列名放在括号之间,但也会转义字符,这些字符会打断您引用的列名,并可能导致SQL注入

例如:

SELECT QUOTENAME('abc[]def'); 
将返回:

[abc[]]def]  

有关更多信息:

请提供有关如何防止注射的更多详细信息。如果您在用户输入字符串周围使用QUOTENAME,则类似的内容不会成为问题。选择QUOTENAME('or 1=1;truncate table Users')@user2216-添加的示例
[abc[]]def]