我创建了一个存储过程,该存储过程从表中接受唯一项的值并在该表中搜索它。如果存在,则返回该行的主键列的值。如果它不存在,请立即返回1234进行测试。
这就是我写的方式:
CREATE PROCEDURE dbo.MyTestSP
@ExID VARCHAR(64)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ExIDPK INT;
SELECT @ExIDPK = ExPK
FROM
dbo.EXIDs
WHERE
EXISTS(SELECT 1 FROM dbo.EXIDs WHERE ExID = @ExID);
IF @ExID IS NOT NULL
BEGIN
RETURN @ExIDPK;
END;
ELSE
BEGIN
RETURN 1234;
END;
END;
这是为了测试我的称呼方式:
EXEC MyTestSP 'ewedweweewe';
但它总是返回此:
过程试图返回状态NULL,这是不允许的。而是返回状态0。
我在这里做什么错了?
答案 0 :(得分:2)
事物的结合。
您的检查是否错误。您正在检查@ExID
而不是@ExIDPK
,并且根据您的proc定义,@ExID
不能为空
我建议您也将exist
逻辑也更改为更简单的where
子句
请参见下面的代码
CREATE PROCEDURE dbo.MyTestSP
@ExID VARCHAR(64)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ExIDPK INT;
SELECT @ExIDPK = ExPK
FROM
dbo.EXIDs
WHERE ExID = @ExID;
RETURN ISNULL(@ExIDPK,1234);
END;
答案 1 :(得分:2)
根据您的过程,将变量声明为DECLARE @ExIDPK INT;
,因此默认值为NULL
。如果传递的值在表中不存在,则SP将返回NULL
,这就是为什么收到此消息的原因。
此外,由于您有参数,因此无需在where子句中使用EXISTS()
,只需执行简单的检查即可。并且END
的{{1}}中有一个多余的分号
IF
这是错误的,您根本不需要IF @ExID IS NOT NULL -- you are checking the wrong variable here too
BEGIN
RETURN @ExIDPK;
END;
ELSE
BEGIN
RETURN 1234;
END;--This one
,只需简单一点即可
IF
这将确保您的变量永远不会为CREATE PROCEDURE dbo.MyTestSP
@ExID VARCHAR(64)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ExIDPK INT = 1234; --Will ensure your variable never be NULL
SELECT @ExIDPK = ExPK
FROM
dbo.EXIDs
WHERE ExID = @ExID;
RETURN @ExIDPK;
END;
,因为您设置了默认值,如果查询不返回任何行(0行),该默认值将保持不变。
最后,我建议不要使用NULL
代码,而是使用OUTPUT参数(甚至是SELECT)。
程序中的流程控制块中通常使用返回码来为每种可能的错误情况设置返回码值
答案 2 :(得分:0)
由于这个问题是基于对返回值的机制的理解而提出的,因此,我将其更多地发布为首选的机制。通常,返回码/返回值是为错误代码保留的,错误代码为0,成功代码为非0(非0表示成功)(值得注意的例外是SQL Server代理run_status。
下面的代码示例将允许您测试不同的情况:
if object_id(N'[test].[table_01]', N'U') is not null
drop table [test].[table_01];
go
create table [test].[table_01]
(
[id] [int] identity(1, 1) not null,
constraint [test__table_01__id__pk] primary key clustered([id])
, [value] varchar(64)
);
go
insert into [test].[table_01]
([value])
values ('red'),
('green'),
('blue');
go
if object_id(N'[test].[get__name__id]', N'P') is not null
drop procedure [test].[get__name__id];
go
create procedure [test].[get__name__id] @value varchar(64)
, @id [int] = null output
as
begin
set transaction isolation level read uncommitted;
set NOCOUNT on;
select @id = [id]
from [test].[table_01]
where [value] = @value;
end;
go
--
declare @pk [int]= null
, @value [varchar](64)='test';
execute [test].[get__name__id]
@value=@value
, @id=@pk output;
if @pk is not null
begin
select @pk as [primary_key__for__value]
, @value as [value];
end;
else
begin
select 'No primary key found for value ' + @value;
end;