2012-10-24 44 views
4

我有一个(遗留)VB6程序需要一些工作。我有一个更新供应商表的存储过程。在这种特殊的形式中,我不需要更新整行,只有20列中的10列。带有可选参数的SQL Server存储过程更新错误的列

下面是一些伪代码,如果我想更新整个行工作正常:

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 

,这一切运行W/O错误,但如果我更新一个可选列,跳了几下,然后更新另一个可选列,将更新错误的列。

更新的实施例使用常规参数:

tblVendor 
ID: 2924 
Vendor ID: Company1 
Vendor Name: Company Name 
Contact: Bob 
email: [email protected] 

通过的时候,不提供“联系”的可选参数更新的实施例:

tblVendor 
ID: 2924 
Vendor ID: Company1 
Vendor Name: Company Name 
Contact: [email protected] 
email: [email protected] 

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

回答

6

您必须在执行存储过程时明确指定参数名称,并为那些您想忽略的参数传入null。示例

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

感谢您的帮助!这是有道理的。 –

+0

通过在执行过程中放置​​'null'不会将它指定为过程的可选对象吗? – WhatsThePoint

+0

不是。当您使用代码中的可选参数调用存储过程时,可以一起省略可选参数。并存储proc将工作。上述要求仅在从SSMS执行存储过程时才成立。没有这个,SQL Server将不知道你没有通过哪个可选参数。你必须明确地声明参数名称和你传递的值。如果这是有道理的。 – Dimitri