【问题标题】:SQL Server error "Operand type clash: varchar is incompatible with int "SQL Server 错误“操作数类型冲突:varchar 与 int 不兼容”
【发布时间】:2021-05-18 07:49:48
【问题描述】:

我已经制作了以下存储过程来备份数据库

CREATE PROCEDURE [dbo].[usp_databasebackup]  
    @DatabaseName NVARCHAR(200),
    @Path NVARCHAR(500)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sqlQuery  VARCHAR(5000)  

    BEGIN
        SET @sqlQuery = ' BACKUP DATABASE ['+@DatabaseName+'] TO DISK = N''D:\@DatabaseName.bak'' 
                          WITH COPY_ONLY, NOFORMAT, NOINIT, NAME = N''@DatabaseName-Full Database Backup'', 
                          SKIP, NOREWIND, NOUNLOAD, STATS =''10'' '

        EXEC (@sqlQuery)
    END
END
GO

当我使用数据库名称和路径作为参数执行存储过程时,我收到此错误:

操作数类型冲突:varchar 与 int 不兼容

【问题讨论】:

  • 警告广泛容易受到注入攻击! '...[' + @SomeString + ']...'注射安全的!每当您注入动态对象时,总是正确地用QUOTENAME 引用它们。 N''D:\@DatabaseName.bak'' 也不行; SQL 不是脚本语言,因此它不会将@DatabaseName(未定义)的值替换为@DatabaseName 的值。看看here 如何将值注入动态语句。
  • 只是一个猜测,但STATS = 不期望一个整数而不是一个字符串?当您在备份语句中手动“填空”并尝试执行时会发生什么?
  • 您正在备份到磁盘位置“D:\@databasename.bak”。 Stats 不应被引用。你甚至不使用@path。你甚至不需要 DSQL,backup database 允许你传递数据库和路径的参数。
  • 旁注:@DatabaseName 应定义为 sysnamenvarchar(128) NOT NULL 的同义词,这是 SQL Server 用于所有对象名称的数据类型。

标签: sql-server


【解决方案1】:

您可以在不使用动态 SQL 的情况下备份数据库。

你只需要像这样使用备份命令

backup database @DatabaseName
to disk=@DiskName
with name=@Name,
compression, format, init, skip, norewind, nounload, stats=10

@DatabaseName 应该是sysname

在备份命令中使用变量之前,您需要准备/连接名称和路径 - 即,@DiskName 将是 pathfilename 与“.bak”后缀的连接。

【讨论】:

  • 感谢您的帮助。
  • 现在我得到“不支持原始设备上的备份。'C:' 是原始设备”
  • 在您的问题中,您有with noformat 选中此项并更改为with format
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2020-05-29
相关资源
最近更新 更多