Sql server 如何在存储过程中抛出自定义错误

Sql server 如何在存储过程中抛出自定义错误,sql-server,stored-procedures,Sql Server,Stored Procedures,当引用键丢失时,我想抛出一个错误,但是我想列出丢失的键,而不是通过完整性检查失败。我已经创建了下面的工作。然而,我希望有一种方法可以优化它并减少代码行数 DECLARE @NonRefKeys INT SELECT @NonRefKeys = SUM(1) FROM staging.Sale sa WHERE NOT EXISTS ( SELECT cu.Customer_Shipping_ID FROM staging.Customer cu WHERE LTRIM(

当引用键丢失时,我想抛出一个错误,但是我想列出丢失的键,而不是通过完整性检查失败。我已经创建了下面的工作。然而,我希望有一种方法可以优化它并减少代码行数

DECLARE @NonRefKeys INT

SELECT @NonRefKeys = SUM(1)
FROM staging.Sale sa
WHERE NOT EXISTS (
    SELECT cu.Customer_Shipping_ID
    FROM staging.Customer cu
    WHERE LTRIM(RTRIM(sa.Customer_Shipping_ID)) = LTRIM(RTRIM(cu.Customer_Shipping_ID)))

IF @NonRefKeys IS NOT NULL
BEGIN

IF OBJECT_ID('tempdb..#Missing_Ref') IS NOT NULL
DROP TABLE #Missing_Ref;

SELECT sa.Customer_Shipping_ID AS ID
INTO #Missing_Ref
FROM staging.Sale sa
WHERE NOT EXISTS (
        SELECT cu.Customer_Shipping_ID
        FROM staging.Customer cu
        WHERE LTRIM(RTRIM(sa.Customer_Shipping_ID)) = LTRIM(RTRIM(cu.Customer_Shipping_ID)))

DECLARE @Current_ID VARCHAR(50);
DECLARE @Missing_ID VARCHAR(MAX) = '';
DECLARE @Output_Error VARCHAR(MAX);

DECLARE id_cursor CURSOR FOR
SELECT ID
FROM #Missing_Ref;

OPEN id_cursor
FETCH NEXT FROM id_cursor INTO @Current_ID

WHILE @@FETCH_STATUS = 0
BEGIN
    IF (@Missing_ID != '')
        SET @Missing_ID = @Missing_ID + ', ';

    SET @Missing_ID = @Missing_ID + @Current_ID;

    FETCH NEXT FROM id_cursor INTO @Current_ID
END
CLOSE id_cursor
DEALLOCATE id_cursor

SET @Output_Error = 'ERROR: Key/s ' + @Missing_ID + ' for Customer Shipping ID missing from Customer table';

RAISERROR (@Output_Error,16,1)
END

看看这个。。。您可以更新变量,而无需创建临时表

有一个尾随的“,”必须删除

Declare @MissingIDList VarChar (Max) = ''

DROP Table #MyTableOfMissingIds

Select *
Into #MyTableOfMissingIds
From 
(   Select 1 MissingId
    Union Select 2
    Union Select 3
    Union Select 4
    Union Select 5
    Union Select 6
) xx

Update #MyTableOfMissingIds
Set @MissingIDList = @MissingIDList + Cast (MissingId as VarChar) + ','

Declare @Output_Error VarChar (Max)
SET @Output_Error = 'ERROR: Key/s ' + @MissingIDList + ' for Customer Shipping ID missing from Customer table';

RAISERROR (@Output_Error,16,1)
我的示例中的
Update
语句可以替换为这样的一个表(OTTOMH,因此可能需要验证语法)

现在,如果您擅长使用XML,下面是另一个很酷的方法:

Declare @MissingIDList VarChar (Max) = ''
Declare @Output_Error VarChar (Max)

DROP Table #MyTableOfMissingIds

Select *
Into #MyTableOfMissingIds
From 
(   Select 1 MissingId
    Union Select 2
    Union Select 3
    Union Select 4
    Union Select 5
    Union Select 6
) xx

SELECT @MissingIDList = 
    SUBSTRING(
                (   SELECT ',' + Cast (MissingId as VarChar)
                    FROM #MyTableOfMissingIds s
                    ORDER BY 1
                    FOR XML PATH('')
                )
                ,2,200000
            )

SET @Output_Error = 'ERROR: Key/s ' + @MissingIDList + ' for Customer Shipping ID missing from Customer table';

RAISERROR (@Output_Error,16,1)

看看这个。。。您可以更新变量,而无需创建临时表

有一个尾随的“,”必须删除

Declare @MissingIDList VarChar (Max) = ''

DROP Table #MyTableOfMissingIds

Select *
Into #MyTableOfMissingIds
From 
(   Select 1 MissingId
    Union Select 2
    Union Select 3
    Union Select 4
    Union Select 5
    Union Select 6
) xx

Update #MyTableOfMissingIds
Set @MissingIDList = @MissingIDList + Cast (MissingId as VarChar) + ','

Declare @Output_Error VarChar (Max)
SET @Output_Error = 'ERROR: Key/s ' + @MissingIDList + ' for Customer Shipping ID missing from Customer table';

RAISERROR (@Output_Error,16,1)
我的示例中的
Update
语句可以替换为这样的一个表(OTTOMH,因此可能需要验证语法)

现在,如果您擅长使用XML,下面是另一个很酷的方法:

Declare @MissingIDList VarChar (Max) = ''
Declare @Output_Error VarChar (Max)

DROP Table #MyTableOfMissingIds

Select *
Into #MyTableOfMissingIds
From 
(   Select 1 MissingId
    Union Select 2
    Union Select 3
    Union Select 4
    Union Select 5
    Union Select 6
) xx

SELECT @MissingIDList = 
    SUBSTRING(
                (   SELECT ',' + Cast (MissingId as VarChar)
                    FROM #MyTableOfMissingIds s
                    ORDER BY 1
                    FOR XML PATH('')
                )
                ,2,200000
            )

SET @Output_Error = 'ERROR: Key/s ' + @MissingIDList + ' for Customer Shipping ID missing from Customer table';

RAISERROR (@Output_Error,16,1)
这确实是一个问题,但仅仅减少代码行数并不是一个优化。因为我们花在阅读代码上的时间远远多于编写代码上的时间,所以我们的首要任务应该始终是拥有清晰、可读、可维护的代码,这些代码能够正确地工作,并且可以接受地执行。有多少行代码根本不应该考虑。这确实应该考虑,但仅仅减少代码行数并不是一种优化。因为我们花在阅读代码上的时间远远多于编写代码上的时间,所以我们的首要任务应该始终是拥有清晰、可读、可维护的代码,这些代码能够正确地工作,并且可以接受地执行。有多少行代码根本不应该考虑。更新在#MyTableOfMissingId上,不管您如何设置@MissingIDList。我运行了它,它工作了,尽管没有什么意义S@stats101,#MyTableOfMissingId是源代码。当您使用where子句进行更新时,所有行都将与所使用的任何变量一起用作源和目标。诀窍是更新变量@MissingIDList,由于更新是逐行进行的,因此会产生串联效果,因为您已将其设置为
@MissingIDList=@MissingIDList+MissingIdColumn+,'
。更新在#MyTableOfMissingIds上,但您设置了@MissingIDList。我运行了它,它工作了,尽管没有什么意义S@stats101,#MyTableOfMissingId是源代码。当您使用where子句进行更新时,所有行都将与所使用的任何变量一起用作源和目标。诀窍是更新变量@MissingIDList,由于更新是逐行进行的,因此会得到一个串联效果,因为您已将其设置为
@MissingIDList=@MissingIDList+MissingIdColumn+,'