在 SQL Server 存储过程中的 If Else

47
我创建了以下存储过程:

CREATE PROCEDURE procedure_name

Create Procedure sp_ADD_USER_EXTRANET_CLIENT_INDEX_PHY
(
@ParLngId int output
)
as
Begin
    SET @ParLngId = (Select top 1 ParLngId from T_Param where ParStrNom = 'Extranet Client')
    if(@ParLngId = 0)
        begin
            Insert Into T_Param values ('PHY', 'Extranet Client', Null, Null, 'T', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL)
            SET @ParLngId = @@IDENTITY
        End
    Return @ParLngId
End

所以我设置了一个变量@ParLngId,我检查表中是否有这样的数据,如果有,我返回该值,如果没有,则插入一条并返回包含插入行Id的变量...但现在它显示了一个SqlException:

子查询返回了更多的值。当子查询跟随=,!=,<,<=,>,> =或用作表达式时,不允许这样做。

有人有解决方案吗?


“返回不同值的错误” - 请问您能否编辑错误消息的确切文本? - AakashM
你能复制/粘贴完整的错误信息吗? - UnhandledExcepSean
我刚刚编辑了这篇文章。 - Hubert Solecki
3
CREATE PROCEDURE:在为存储过程命名时,避免使用 sp_ 前缀。该前缀被 SQL Server 用于指定系统存储过程。如果存在同名的系统存储过程,则使用该前缀可能会导致应用程序代码出现故障。 - Damien_The_Unbeliever
1
是的,但是当您在SQL Server中添加一个存储过程时,它会首先验证是否存在具有相同名称的存储过程,然后再进行添加。 - Hubert Solecki
显示剩余2条评论
8个回答

57

谢谢大家的回答,但我已经想到了如何做,最终的步骤如下:

Create Procedure sp_ADD_RESPONSABLE_EXTRANET_CLIENT
(
@ParLngId int output
)
as
Begin
if not exists (Select ParLngId from T_Param where ParStrIndex = 'RES' and ParStrP2 = 'Web')
    Begin
            INSERT INTO T_Param values('RES','¤ExtranetClient', 'ECli', 'Web', 1, 1, Null, Null, 'non', 'ExtranetClient', 'ExtranetClient', 25032, Null, 'informatique.interne@company.fr', 'Extranet-Client', Null, 27, Null, Null, Null, Null, Null, Null, Null, Null, 1, Null, Null, 0 )
            SET @ParLngId = @@IDENTITY
    End
Else
    Begin
            SET @ParLngId = (Select top 1 ParLngId from T_Param where ParStrNom = 'Extranet Client')
            Return @ParLngId
    End   
End

因此,我发现并使其工作的是:

如果不存在

这允许我们使用布尔值而不是 Null0 或由 count() 得出的数字。


11
如果没有匹配的行,则@ParLngId将是NULL而不是零,所以您需要使用IF @ParLngId IS NULL。 您还应该使用SCOPE_IDENTITY()而不是@@IDENTITY

@@Identity是有效的。在我不需要使用Else If时它就有效了,我不认为问题来自于它。 - Hubert Solecki

9

试试这个-

CREATE PROCEDURE sp_ADD_USER_EXTRANET_CLIENT_INDEX_PHY
AS
BEGIN

    DECLARE @ParLngId INT
    SELECT TOP 1 @ParLngId = ParLngId
    FROM dbo.T_Param
    WHERE ParStrNom = 'Extranet Client'

    IF (@ParLngId = 0)
    BEGIN
        INSERT INTO dbo.T_Param
        VALUES ('PHY', 'Extranet Client', NULL, NULL, 'T', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL)

        RETURN SCOPE_IDENTITY()
    END
    ELSE BEGIN

        RETURN @ParLngId 

    END

END

4

尝试使用连接查询语句

CREATE PROCEDURE [dbo].[deleteItem]
@ItemId int = 0 
AS
 Begin
 DECLARE @cnt int;

SET NOCOUNT ON
SELECT @cnt =COUNT(ttm.Id) 
    from ItemTransaction itr INNER JOIN ItemUnitMeasurement ium 
        ON itr.Id = ium.ItemTransactionId  INNER JOIN ItemMaster im 
        ON itr.ItemId = im.Id INNER JOIN TransactionTypeMaster ttm 
        ON itr.TransactionTypeMasterId = ttm.Id 
        where im.Id = @ItemId

if(@cnt = 1)
    Begin
    DECLARE @transactionType varchar(255);
    DECLARE @mesurementAmount float;
    DECLARE @itemTransactionId int;
    DECLARE @itemUnitMeasurementId int;

        SELECT @transactionType = ttm.TransactionType,  @mesurementAmount = ium.Amount, @itemTransactionId = itr.Id, @itemUnitMeasurementId = ium.Id
        from ItemTransaction itr INNER JOIN ItemUnitMeasurement ium 
            ON itr.Id = ium.ItemTransactionId INNER JOIN TransactionTypeMaster ttm 
            ON itr.TransactionTypeMasterId = ttm.Id 
            where itr.ItemId = @ItemId  
        if(@transactionType = 'Close' and @mesurementAmount = 0)
            Begin
                delete from ItemUnitMeasurement where Id = @itemUnitMeasurementId;

            End
        else
            Begin
                delete from ItemTransaction where Id = @itemTransactionId;
            End
    End
else
 Begin
    delete from ItemMaster where Id = @ItemId;
 End
END

2
if not exists (select dist_id from tbl_stock where dist_id= @cust_id and item_id=@item_id)
    insert into tbl_stock(dist_id,item_id,qty)values(@cust_id, @item_id, @qty); 
else
    update tbl_stock set qty=(qty + @qty) where dist_id= @cust_id and item_id= @item_id;

0

0

您可以尝试以下存储过程 Sql:

Create Procedure sp_ADD_USER_EXTRANET_CLIENT_INDEX_PHY
(
@ParLngId int output
)
as
Begin
    -- Min will return only 1 value, if 'Extranet Client' is found
    -- IsNull will take care of 'Extranet Client' not found, returning 0 instead of Null
    -- But T_Param must be a Master Table with ParStrNom having a Unique Index, if so Min is not reqd at all
    -- But 'PHY', 'Extranet Client' suggests that Unique Key has 2 columns, not just ParStrNom

    SET @ParLngId = IsNull((Select Min (ParLngId) from T_Param where ParStrNom = 'Extranet Client'), 0);

    -- Nothing changed below

    if  (@ParLngId = 0)
        Begin
            Insert Into T_Param values ('PHY', 'Extranet Client', Null, Null, 'T', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL)
            SET @ParLngId = @@IDENTITY
    End

    Return  @ParLngId
    End

-2

不要写成:

Select top 1 ParLngId from T_Param where ParStrNom = 'Extranet Client'

请编写:

Select top 1 ParLngId from T_Param where ParStrNom IN 'Extranet Client'

即用'IN'替换'='符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接