带有可选参数的SQL Server存储过程会更新错误的列

时间:2012-10-24 22:37:03

标签: sql-server tsql stored-procedures optional-parameters

我有一个(遗留的)VB6程序需要一些工作。我有一个更新供应商表的存储过程。在这种特殊的形式中,我不需要更新整行,只需要20个左右的列。

如果我想要更新整行,这里有一些伪代码可以正常工作:

CREATE PROCEDURE [dbo].[spUpdateVendor](
    @pID INT,
    @pVendorID varchar(254), 
    @pVendorName varchar(255),
    @pContact varchar(255),
    @pEmail varchar(255),
    ...)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON

DECLARE @ErrorMessage nvarchar(4000);

BEGIN TRY
-- Start the transaction
    BEGIN TRANSACTION
        UPDATE tblVendor
            SET
                [Vendor ID] = @pVendorID,
                [Vendor Name] = @pVendorName,
                [Contact] = @pContact,
                [email] = @pEmail
                ...
            WHERE
                [ID] = @pID
    COMMIT TRANSACTION;
END TRY

如果我只想更新一些带有数据的列,那么就是我尝试过的(伪)代码(尝试使用可选参数):

CREATE PROCEDURE [dbo].[spUpdateVendor2](
    @pID INT,
    @pVendorID varchar(254) = NULL, 
    @pVendorName varchar(255) = NULL,
    @pContact varchar(255) = NULL,
    @pEmail varchar(255) = NULL,
    ...)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON

DECLARE @ErrorMessage nvarchar(4000);

BEGIN TRY
-- Start the transaction
    BEGIN TRANSACTION
        UPDATE tblVendor
            SET
                [Vendor ID] = ISNULL(@pVendorID,[Vendor ID]),
                [Vendor Name] = ISNULL(@pVendorName,[Vendor Name]),
                [Contact] = ISNULL(@pContact,[Contact]),
                [Email] = ISNULL(@pEmail,[email]),
                ...
            WHERE
                [ID] = @pID 
    COMMIT TRANSACTION;
END TRY

并且它都运行没有错误但是如果我更新一个可选列,跳过一些,然后更新另一个可选列,它将更新错误的列。

使用常规参数进行更新的示例:

tblVendor
ID: 2924
Vendor ID: Company1
Vendor Name: Company Name
Contact: Bob
email: bob@company.com

当我不提供“联系”时,通过可选参数进行更新的示例:

tblVendor
ID: 2924
Vendor ID: Company1
Vendor Name: Company Name
Contact: bob@company.com
email: bob@company.com

因此它更新了行,但它更新了错误的列。我做错了什么?

1 个答案:

答案 0 :(得分:7)

执行存储过程时必须显式指定参数名称,并为要省略的人传入null。实施例

exec spUpdateVendor2 @pID=102, @pVendorID = 1, @pVendorName = NULL, @pContact = 'Contact',
@pEmail = NULL ...