Sql Server 2008 sp_executesql语法帮助 - 我想我的报价不正确

问题描述:

使用SQL Server 2008我试图建立一个字符串并用sp_executesql执行它。我显然有一些引号错误。它似乎运行,但数据库不会丢失。有人可以帮我纠正语法吗?Sql Server 2008 sp_executesql语法帮助 - 我想我的报价不正确

USE [master] 
GO 

DECLARE @sql NVARCHAR(500) 
SET @sql = N' IF EXISTS (SELECT NAME FROM master.sys.databases sd where name =''@DBName'') 
BEGIN 
    ALTER DATABASE [@DBName] SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE 
    ALTER DATABASE [@DBName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
    DROP DATABASE [@DBName] 
END'; 

EXECUTE sp_executesql @sql, N'@DBName sysname', @DBName = 'ReapirInformation' 

GO 

我试过添加和删除引号,但我似乎无法拨入正确的组合。任何提示或技巧都是值得欢迎的。

感谢,
〜CK在圣地亚哥

+1

你是否有任何错误,或者它只是在默默地失败?您是否试过在ELSE语句中输出一些内容,让您知道您的“EXISTS”if语句是否为false? – 2011-06-08 20:49:34

动态SQL不喜欢的工作。
您仍然无法将参数传递给将用于替代对象名称的动态字符串。

您必须自己构造查询字符串,手动将@DBName替换为实际值。但是,您可以在等式的右侧使用参数,而不用引号。

此外,将对象名称放入查询中时,请始终使用QUOTENAME函数。它将正确地转义该名称,所以不存在由对象名称中的某些字符引起的sql注入或不需要的行为。

SET @sql = N' IF EXISTS (SELECT NAME FROM master.sys.databases sd where name = @DBName) 
BEGIN 
    ALTER DATABASE ' + quotename(@DBName, '[') + N' SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE 
    ALTER DATABASE ' + quotename(@DBName, '[') + N' SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
    DROP DATABASE ' + quotename(@DBName, '[') + N' 
END'; 
+0

是的你是对的。你的第一个解决方案奏效我结束了这样做DECLARE @DBName sysname SET @DBName ='RepairInformation' DECLARE @sql NVARCHAR(500) SET @sql = N'IF EXISTS(SELECT NAME FROM master.sys。数据库sd其中name = N'''+ @DBName +''') BEGIN \t ALTER DATABASE ['+ @DBName +'] SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE ALTER DATABASE ['+ @DBName +'] SET SINGLE_USER WITH ROLLBACK IMMEDIATE DROP DATABASE ['+ @DBName +'] END' EXECUTE sp_executesql @sql – Hcabnettek 2011-06-08 22:20:34

试试这个:

USE [master] 
GO 

DECLARE @sql NVARCHAR(500) 
SET @sql = N' IF EXISTS (SELECT NAME FROM master.sys.databases sd where name [email protected]) 
BEGIN 
    ALTER DATABASE [@DBName] SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE 
    ALTER DATABASE [@DBName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
    DROP DATABASE [@DBName] 
END'; 

EXECUTE sp_executesql @sql, N'@DBName sysname', @DBName = 'ReapirInformation' 

GO 
+0

不,这是行不通的。它可以解析,但不会丢失数据库。 – Hcabnettek 2011-06-08 21:06:42

+0

@Hcabnettek,你确定DBName是正确的。检查'ReapirInformation'。 – 2011-06-08 21:21:36

  1. 你在if exists查询报价@DbName,所以它是不会把它当作一个绑定变量,因此在不是替代名称传入。因此,寻找'@DBName'的搜索找不到任何内容,if exists为假,并且SQL运行完毕。
  2. 修复1后,您在后面三行中引用了@DBName,因此不会替换该值,并将尝试更改@DBName而不是@DBName的值,并尝试删除@DBName而不尝试@DBName的值。
  3. 我不认为你可以使用数据库名称的绑定变量,但我可能是错的。如果你不能,你将需要建立动态的字符串:

    set @SQL = N' IF EXISTS (SELECT NAME FROM master.sys.databases sd where name [email protected]) BEGIN ALTER DATABASE ' + QUOTENAME('ReapirInformation') + N' SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE ALTER DATABASE ' + QUOTENAME('ReapirInformation') + N' SET SINGLE_USER WITH ROLLBACK IMMEDIATE DROP DATABASE ' + QUOTENAME('ReapirInformation') + N' END'; 
    

[OT:为什么计算器失去的时候我复制和粘贴换行符?]

或者类似的东西:

SET @sql = N' IF EXISTS (SELECT NAME FROM master.sys.databases sd where name [email protected]) 
BEGIN 
    ALTER DATABASE ##@DBName## SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE 
    ALTER DATABASE ##@DBName## SET SINGLE_USER WITH ROLLBACK IMMEDIATE 
    DROP DATABASE ##@DBName## 
END'; 
SET @DBName = N'ReapirInformation'; 
SET @sql = replace(@sql, N'##@DBNAME##', QUOTENAME(@DBName) 
EXECUTE sp_executesql @sql, N'@DBName sysname', @DBName = @DBName 

警告未测试,无法访问SQL Server方便。