SQL Server存储过程统计表行数异常:始终返回-1求助
问题分析与修正
你的存储过程存在两个核心问题,导致即便表存在也始终输出-1:
- OBJECT_ID参数错误:
OBJECT_ID ('@Table_Name')中的单引号会将@Table_Name当作字符串字面量处理,而非变量的实际值,因此永远无法匹配到目标表,直接进入ELSE分支输出-1。 - 静态SQL不支持变量作为表名:
FROM CONCAT('dbo.', @Table_Name)的写法在静态SQL中无效,SQL Server无法识别拼接后的字符串为合法表名。
以下是修正后的完整代码:
CREATE PROCEDURE test_pro (@Table_Name varchar(50)) AS BEGIN -- 检查指定用户表是否存在,N'U'参数限定仅匹配用户表类型 IF OBJECT_ID(N'dbo.' + @Table_Name, N'U') IS NOT NULL BEGIN -- 用动态SQL实现变量表名的行数统计,QUOTENAME防止SQL注入 DECLARE @Sql NVARCHAR(MAX) SET @Sql = N'SELECT COUNT(*) AS num_rows FROM dbo.' + QUOTENAME(@Table_Name) EXEC sp_executesql @Sql END ELSE BEGIN -- 表不存在时统一用SELECT返回-1,保持输出格式一致 SELECT -1 AS num_rows END END GO -- 测试存储过程 EXEC test_pro training_kehila -- 按需删除存储过程 IF OBJECT_ID ('test_pro') IS NOT NULL DROP PROCEDURE test_pro
关键修改说明:
- OBJECT_ID的正确使用:通过
N'dbo.' + @Table_Name拼接完整表名,搭配N'U'参数精准检查用户表,避免误判其他类型数据库对象。 - 动态SQL处理变量表名:借助
sp_executesql执行动态拼接的SQL语句,同时用QUOTENAME()函数处理表名中的特殊字符,规避SQL注入风险。 - 统一输出逻辑:无论表是否存在都用
SELECT返回结果,方便调用方统一处理返回值,替代原代码中SELECT与PRINT混用的方式。
内容的提问来源于stack exchange,提问作者Adrian Smith
相关产品推荐
相关产品推荐

