用于删除数据库的Buggy查询

时间:2014-11-21 17:09:13

标签: sql sql-server sql-server-2008

我有一个查询,我已经将其包含在批处理文件中,该文件应该在运行另一个将再次重新创建和填充数据库的进程之前自动删除数据库。我用过这个查询

declare @dbname nvarchar (2000);
declare @query nvarchar (max);

DECLARE db_cursor CURSOR FOR  
select name from sys.databases 
where name like '%ABCDir%' 

Open db_cursor
fetch next from db_cursor into @dbname

while @@FETCH_STATUS = 0 

BEGIN
  set @query = 'Drop Database ['+ @dbname + ']' 
  Exec(@query)

  FETCH NEXT FROM db_cursor INTO @dbname 

END
Close db_cursor
deallocate db_cursor

问题在于它没有删除所有内容。每次运行的结果将填充另一个表,当我运行后续运行时,我将获得当前运行中先前运行的结果。 Anyboyd看到如何设置此查询的错误?

1 个答案:

答案 0 :(得分:0)

此脚本将确保您连接到该数据库,然后将数据库模式更改为单个用户,这意味着只有一个用户可以连接到数据库,然后您将连接到Master数据库,它将保留数据库以便与没有连接,最后你可以删除数据库。

同样使用适当的数据类型,您的数据库永远不会是2000个字符,那么为什么要使用varchar 2000的变量,使用特定的SYSNAME数据类型来存储sql server对象名。

使用QUOTENAME()函数在数据库名称周围放置方括号。使您的代码看起来更干净,并保护您免受可能的SQL注入攻击。

declare @dbname SYSNAME;
declare @query  NVARCHAR(max);

DECLARE db_cursor CURSOR FOR  
select name from sys.databases 
where name like '%ABCDir%' 

Open db_cursor
fetch next from db_cursor into @dbname

WHILE (@@FETCH_STATUS = 0) 
BEGIN
   SET @query = N' USE ' + QUOTENAME(@dbname) 
              + N' ALTER DATABASE ' + QUOTENAME(@dbname) 
              + N' SET SINGLE_USER WITH ROLLBACK IMMEDIATE; '  
              + N' USE master;'
              + N' Drop Database '  + QUOTENAME(@dbname) + '' 

  EXEC sp_executesql @query 

  FETCH NEXT FROM db_cursor INTO @dbname 

END

Close db_cursor
deallocate db_cursor