一个sqlserver存储过程,创建时没报错,执行时有错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个sqlserver存储过程,创建时没报错,执行时有错误相关的知识,希望对你有一定的参考价值。

create proc cp_query
@mantype varchar(20),
@name varchar(50),
@type varchar(10),
@num int output
as
begin
exec('select '+@num+'=count(*) from tb_mail where'+ @mantype+'='+@name +'and type='+@type)
end

执行时
declare @num int
exec cp_query 'receiveman','hao@softeem.com','normal',@num output
一直报“=”后面有错误

参考技术A 正确的语句如下:
exec('select @num=count(*) from tb_mail where'+ @mantype+'=@name and type=@type‘)
要注意的就是:如果将数据表中的字段名作为参数进行传参时,要放在引号外面的
给你举个例子:
ALTER PROCEDURE [dbo].[Gets](
@tb varchar(10), --这个参数是为了传参数据库表中的一个字段名
@fieldname varchar(10) --这个参数是为了传参数据库表的表名
)
AS
BEGIN
set xact_abort on
begin transaction
declare @sql_text nvarchar(4000)
set @sql_text = 'select distinct ' + @fieldname + ' from ' + @tb --这两个参数传参的内容都是数据库中有定义的东西(一个是字段,一个是表名),而不是普通的参数,所以这两个参数要放在引号外面,而普通的参数直接放在引号里面即可
exec(@sql_text) --执行此语句
commit transaction
END
参考技术B 拼接的语法上@num是INT型的要转化成字符型,对@num要进行类型转化成varchar
从语句的意义看来看,@num不应该加载'+...+'里,这样的意思是@num的值=count(*),而不是把count(*)赋值给@num,正确的应该是('select @num=count(*) from tb_mail where'+ @mantype+'='+@name +'and type='+@type)
参考技术C create proc cp_query
@mantype varchar(20),
@name varchar(50),
@type varchar(10),
@num int output
as
BEGIN
DECLARE @s NVARCHAR(2000)
SET @s='select @num=count(*) from tb_mail where '''+ @mantype+'''='''+@name+''' and type='+@type
EXEC sp_executesql @s,N'@num int output',@num OUTPUT
end
go

--执行时
declare @num int
exec cp_query 'receiveman','hao@softeem.com','normal',@num OUTPUT
SELECT @num

go变量传参用sp_executesql追问

谢谢,可是执行的时候还是一直报‘normal’列明无效啊

追答

少了引號

create proc cp_query
@mantype varchar(20),
@name varchar(50),
@type varchar(10),
@num int output
as
BEGIN
DECLARE @s NVARCHAR(2000)
SET @s='select @num=count(*) from tb_mail where '''+ @mantype+'''='''+@name+''' and type='''+@type+''''
EXEC sp_executesql @s,N'@num int output',@num OUTPUT
end
go
以下兩個參數是列名還是值,是值加引號,不是參時不用加
@mantype varchar(20),
@name varchar(50),

本回答被提问者采纳

SQLSERVER创建该存储过程时不会出错,但是执行存储过程时报错

创建该存储过程时,不会出错,但是执行存储过程时,会报出下面这样的错误

这是因为在存储过程创建时,它先做语法检查,如果通过了语法检查,它会尝试解析它包含的对象名,如果存在也会解析该对象引用的对象是否存在。如果引用的对象名不存在,解析会在存储过程首次执行时触发。即在首次执行存储过程时,查询处理器从 sys.sql_modules 目录视图中读取该存储过程的文本,并检查该过程所使用的对象名称是否存在。这一过程称为延迟名称解析,因为存储过程引用的表对象不需要在创建该存储过程时就存在,而只需在执行该存储过程时存在。

注意:  

只有当引用的表对象不存在时才能使用延迟名称解析。所有其他对象在创建所存储的过程时必须存在。例如,引用所存储的过程中的一个现有表时,不能列出该表不存在的列。

 

---存储过程删除中间表R_LDBG_B1_TEMP,但这条没执行成功。

if OBJECT_ID(\'R_LDBG_B1_TEMP\',\'U\') IS NOT NULL
   drop table R_LDBG_B1_TEMP

原因分析: R_LDBG_B1_TEMP表字段结构在执行另一个存储过程时发生变化导致其它存储过程引用了不存在的字段。

执行存储过程时先解析,当发现引用表中不存在的字段就会直接报错,无法执行。

 

有两个解决办法:

1) 在外部编程执行存储过程前删除中间表。

2) 在存储过程内部执行最后删除中间表。

以上是关于一个sqlserver存储过程,创建时没报错,执行时有错误的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver 存储过程调用报错

sqlserver里存储过程怎么调用存储过程

sqlserver如何自动调用存储过程, 24小时执行一次?

关于sqlserver存储过程的问题

SQLSERVER创建该存储过程时不会出错,但是执行存储过程时报错

sqlserver 怎么看存储过程的上次执行时间