You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行带参数SQL Server存储过程时提示无参数错误求助

存储过程执行报错:“Procedure has no parameters and arguments were supplied” 解决方法

我为存储过程RestoreBackups声明了参数并传入对应值,但执行时始终报错:

Procedure has no parameters and arguments were supplied.

以下是存储过程代码、执行代码及错误详情:

存储过程代码

USE [ns_lots_of_vlfs]
GO

/****** Object:  StoredProcedure [dbo].[RestoreBackups]    Script Date: 16/02/2023 10:49:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Restorebackups] (@DatabaseName     VARCHAR(500),
                                        @DatabaseNameCopy VARCHAR(5000),
                                        @RestoreDate      DATETIME,
                                        @DiffDate         DATETIME = NULL,
                                        @LogDate          DATETIME = NULL)
AS
    DECLARE @FullBackupSQL                 NVARCHAR(max),
            @DiffBackupSQL                 NVARCHAR(max),
            @LogBackupSQL                  NVARCHAR(max),
            @FullBackupDate                DATETIME,
            @FullBackupFile                NVARCHAR(max),
            @DiffBackupFile                NVARCHAR(max),
            @LogbackupFile                 NVARCHAR(max),
            @FullBackupFileCopy            VARCHAR(5000),
            @FullBackupFileCopyldf         VARCHAR(5000),
            @FullBackupFileCopylocationldf VARCHAR(5000)

    SET NOCOUNT ON

    /* Gets the latest full backup to the restore date declared above for the database name declared above.*/
    SELECT TOP 1 @FullBackupFile = bmf.physical_device_name,
                 @FullBackupDate = bs.backup_finish_date
    FROM   msdb.dbo.backupmediafamily bmf
           INNER JOIN msdb.dbo.backupset bs
                   ON bs.media_set_id = bmf.media_set_id
    WHERE  bs.type = 'D'
           AND bs.database_name = @DatabaseName
           AND bs.backup_finish_date <= @RestoreDate
    ORDER  BY backup_finish_date DESC

    IF NOT EXISTS(SELECT 1
                  FROM   files
                  WHERE  physical_device_name = @FullBackupFile)
      INSERT INTO files
                  (family_sequence_number,
                   physical_device_name,
                   mirror,
                   backup_set_id,
                   backup_set_uuid)
      SELECT TOP 1 family_sequence_number,
                   physical_device_name,
                   mirror,
                   backup_set_id,
                   backup_set_uuid
      FROM   msdb.dbo.backupmediafamily bmf
             INNER JOIN msdb.dbo.backupset bs
                     ON bs.media_set_id = bmf.media_set_id
      WHERE  bs.type = 'D'
             AND bs.database_name = @DatabaseName
             AND bs.backup_finish_date <= @RestoreDate
             AND NOT EXISTS (SELECT physical_device_name
                             FROM   files
                             WHERE  @FullBackupFile = physical_device_name)
      ORDER  BY backup_finish_date DESC

    /* Gets me the latest full backup to the database name declared above. for the data file path location */
    SELECT TOP 1 @FullBackupFileCopy =
    Replace(sd.physical_name, @DatabaseName, @DatabaseNameCopy)
    FROM   sys.master_files sd
    WHERE  sd.type_desc = 'ROWS'
           AND sd.physical_name LIKE '%.mdf'
           AND sd.NAME = @DatabaseName

    SELECT TOP 1 @FullBackupFileCopylocationldf =
    Replace(sl.physical_name, @DatabaseName, @DatabaseNameCopy)
    FROM   sys.master_files sl
    WHERE  sl.NAME LIKE '%log'
           AND sl.type_desc = 'LOG'
           AND sl.NAME LIKE '%' + @DatabaseName + '%'

    SELECT TOP 1 @FullBackupFileCopyldf = sl.NAME
    FROM   sys.master_files sl
    WHERE  sl.NAME LIKE '%log'
           AND sl.type_desc = 'LOG'
           AND sl.NAME LIKE '%' + @DatabaseName + '%'

    SELECT TOP 1 @DiffDate = bs.backup_finish_date,
                 @DiffBackupFile = bmf.physical_device_name
    FROM   msdb.dbo.backupmediafamily bmf
           INNER JOIN msdb.dbo.backupset bs
                   ON bs.media_set_id = bmf.media_set_id
    WHERE  bmf.physical_device_name LIKE '%diff%'
           AND bs.backup_finish_date >= @FullBackupDate
           AND bs.database_name = @DatabaseName
           AND bs.backup_finish_date <= @RestoreDate
           AND bs.type = 'I'
    ORDER  BY backup_finish_date DESC

    IF NOT EXISTS(SELECT 1
                  FROM   files
                  WHERE  physical_device_name = @DiffBackupFile)
      INSERT INTO files
                  (family_sequence_number,
                   physical_device_name,
                   mirror,
                   backup_set_id,
                   backup_set_uuid)
      SELECT TOP 1 family_sequence_number,
                   physical_device_name,
                   mirror,
                   backup_set_id,
                   backup_set_uuid
      FROM   msdb.dbo.backupmediafamily bmf
             INNER JOIN msdb.dbo.backupset bs
                     ON bs.media_set_id = bmf.media_set_id
      WHERE  bs.type = 'I'
             AND bs.database_name = @DatabaseName
             AND bs.backup_finish_date <= @RestoreDate
             AND NOT EXISTS (SELECT physical_device_name
                             FROM   files
                             WHERE  @DiffBackupFile = physical_device_name)
      ORDER  BY backup_finish_date DESC

    SET @FullBackupSQL = 'RESTORE DATABASE ' + @DatabaseNameCopy
                         + '  FROM DISK = ''' + @FullBackupFile
                         + ''' WITH  NORECOVERY,  MOVE '''
                         + @DatabaseName + ''' TO '''
                         + @FullBackupFileCopy + ''', MOVE '''
                         + @FullBackupFileCopyldf + '''   TO '''
                         + @FullBackupFileCopylocationldf
                         + ''' , NORECOVERY,NOUNLOAD, STATS = 5'
    SET @DiffBackupSQL = 'RESTORE DATABASE ' + @DatabaseNameCopy
                         + ' FROM  DISK = ''' + @DiffBackupFile
                         + ''' WITH  FILE = 1,  NOUNLOAD,  STATS = 5'

    IF Object_id('tempdb..#TempTable_log') IS NOT NULL
      DROP TABLE #temptable_log

    SELECT bmf.family_sequence_number,
           bmf.media_family_id,
           bmf.media_count,
           bmf.logical_device_name,
           bmf.physical_device_name,
           bmf.device_type,
           bmf.physical_block_size,
           bmf.mirror,
           bs.backup_set_id,
           bs.backup_set_uuid,
           bs.first_family_number,
           bs.first_media_number,
           bs.last_family_number,
           bs.last_media_number,
           bs.catalog_family_number,
           bs.catalog_media_number,
           bs.position,
           bs.expiration_date,
           bs.software_vendor_id,
           bs.NAME,
           bs.description,
           bs.user_name,
           bs.software_major_version,
           bs.software_minor_version,
           bs.software_build_version,
           bs.time_zone,
           bs.mtf_minor_version,
           bs.first_lsn,
           bs.last_lsn,
           bs.checkpoint_lsn,
           bs.database_backup_lsn,
           bs.database_creation_date,
           bs.backup_start_date,
           bs.backup_finish_date,
           bs.type,
           bs.sort_order,
           bs.code_page,
           bs.compatibility_level,
           bs.database_version,
           bs.backup_size,
           bs.database_name,
           bs.server_name,
           bs.machine_name,
           bs.flags,
           bs.unicode_locale,
           bs.unicode_compare_style,
           bs.collation_name,
           bs.is_password_protected,
           bs.recovery_model,
           bs.has_bulk_logged_data,
           bs.is_snapshot,
           bs.is_readonly,
           bs.is_single_user,
           bs.has_backup_checksums,
           bs.is_damaged,
           bs.begins_log_chain,
           bs.has_incomplete_metadata,
           bs.is_force_offline,
           bs.is_copy_only,
           bs.first_recovery_fork_guid,
           bs.last_recovery_fork_guid,
           bs.fork_point_lsn,
           bs.database_guid,
           bs.family_guid,
           bs.differential_base_lsn,
           bs.differential_base_guid,
           bs.compressed_backup_size,
           bs.key_algorithm,
           bs.encryptor_thumbprint,
           bs.encryptor_type
    INTO   #temptable_log
    FROM   msdb.dbo.backupmediafamily bmf
           INNER JOIN msdb.dbo.backupset bs
                   ON bs.media_set_id = bmf.media_set_id
    WHERE  bs.database_name = @DatabaseName
           AND bs.backup_finish_date <= @RestoreDate
           AND bs.backup_finish_date > @FullBackupDate
           AND bs.backup_finish_date > Isnull(@DiffDate, @FullBackupDate)
           AND bs.type = 'L'

    IF NOT EXISTS(SELECT 1
                  FROM   files
                  WHERE  physical_device_name = @LogbackupFile)
      INSERT INTO files
      SELECT *
      FROM   #temptable_log
      WHERE  physical_device_name NOT IN (SELECT physical_device_name
                                          FROM   files)

    DECLARE @Counter INT

    SET @Counter = 1

    WHILE ( @Counter <= (SELECT Count(*)
                         FROM   #temptable_log) )
      BEGIN
          SELECT TOP 1 @LogbackupFile = physical_device_name,
                       @LogBackupSQL = @LogbackupFile
          FROM   #temptable_log
          WHERE  backup_finish_date > Isnull(@DiffDate, @FullBackupDate)
                 AND backup_finish_date > @FullBackupDate
                 AND backup_finish_date <= @RestoreDate
          ORDER  BY backup_finish_date;

          SET @Counter = 1 -- This should start at one -- 
          /*every time you enter the while loop @counter is a new value so 1 then 2 then 3 and so on which retrieves this from the 
            temp table log.
          */
          SET @LogBackupSQL = 'RESTORE LOG ' + @DatabaseNameCopy
                              + ' FROM  DISK = ''' + @LogbackupFile
                              + ''' WITH  FILE = 1,  NOUNLOAD,  STATS = 5,'

          DELETE FROM #temptable_log
          WHERE  physical_device_name = @LogbackupFile;
      END

    EXEC master..Sp_executesql
      @FullBackupSQL,
      @DiffBackupSQL,
      @LogBackupSQL 

执行代码

USE [ns_lots_of_vlfs]
GO

DECLARE 
     @DatabaseName varchar(500) = 'ns_lots_of_vlfs',
     @DatabaseNameCopy varchar(5000) = 'ns_lots_of_vlfs_COPY',
     @RestoreDate datetime = '2023-02-13 15:45:00.000',
     @DiffDate datetime = null,
     @LogDate datetime = null

EXECUTE [dbo].[RestoreBackups] @DatabaseName, @DatabaseNameCopy, @RestoreDate
GO

错误提示

Procedure has no parameters and arguments were supplied.


问题排查与修复

1. 核心原因:存储过程名称大小写不匹配

你的存储过程定义的名称是[dbo].[Restorebackups](字母b为小写),但执行时调用的是[dbo].[RestoreBackups](字母B为大写)。在区分大小写的数据库排序规则下,SQL Server会将这两个视为完全不同的对象,导致你实际调用的是一个不存在的、无参数的存储过程(或旧版本无参数的同名存储过程)。

2. 修复方案

  • 方案一:统一调用名称
    执行时使用和定义完全一致的名称:
    EXECUTE [dbo].[Restorebackups] @DatabaseName, @DatabaseNameCopy, @RestoreDate
    
  • 方案二:修改存储过程名称
    重新修改存储过程的名称为RestoreBackups(保持大小写一致):
    ALTER PROCEDURE [dbo].[RestoreBackups] (@DatabaseName     VARCHAR(500),
                                            @DatabaseNameCopy VARCHAR(5000),
                                            @RestoreDate      DATETIME,
                                            @DiffDate         DATETIME = NULL,
                                            @LogDate          DATETIME = NULL)
    -- 后续代码保持不变
    

3. 额外检查:确认存储过程存在性

执行以下语句,确认当前数据库中存储过程的正确名称:

SELECT name FROM sys.procedures WHERE name LIKE 'Restore%'

确保调用的名称与查询结果完全一致。

4. 附带问题:动态SQL执行逻辑错误

存储过程最后执行动态SQL的方式有误,sp_executesql只能执行单条语句,不能同时传入多个SQL变量。同时循环逻辑存在死循环问题(@Counter始终被设为1),修正后的执行逻辑如下:

-- 执行全量备份恢复
EXEC sp_executesql @FullBackupSQL;
-- 若差异备份存在则执行
IF @DiffBackupSQL IS NOT NULL
    EXEC sp_executesql @DiffBackupSQL;
-- 执行日志备份恢复(修正循环逻辑)
DECLARE @Counter INT = 1;
DECLARE @TotalLogs INT = (SELECT COUNT(*) FROM #temptable_log);
WHILE @Counter <= @TotalLogs
BEGIN
    SELECT TOP 1 @LogbackupFile = physical_device_name FROM #temptable_log ORDER BY backup_finish_date;
    SET @LogBackupSQL = 'RESTORE LOG ' + @DatabaseNameCopy + ' FROM DISK = ''' + @LogbackupFile + ''' WITH FILE = 1, NOUNLOAD, STATS = 5, NORECOVERY;';
    EXEC sp_executesql @LogBackupSQL;
    DELETE FROM #temptable_log WHERE physical_device_name = @LogbackupFile;
    SET @Counter = @Counter + 1;
END
-- 最后恢复数据库可访问状态
EXEC sp_executesql 'RESTORE DATABASE ' + @DatabaseNameCopy + ' WITH RECOVERY;';

内容的提问来源于stack exchange,提问作者Kushal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:20:20