添加rowguid列会破坏此存储过程吗?

时间:2009-06-09 15:14:43

标签: sql sql-server tsql stored-procedures replication

以下存储过程不允许我将其添加到修改它。尝试修改它时,我收到以下错误 - >

Msg 213, Level 16, State 1, Procedure spPersonRelationshipAddOpposing, Line 51 Insert Error: Column name or number of supplied values does not match table definition.

此外,由于DB已设置为Merge Rep(已添加rowguid列),因此此存储过程现在不再正常工作。

我是否需要更改列的列出方式?设置Merge Rep时的一个警告是 - >

Adding Guid Column MAY Cause INSERT Statements without column lists to Fail

这是什么意思?我该如何解决?

USE [Connect]
GO
/****** Object:  StoredProcedure [dbo].[spPersonRelationshipAddOpposing]    Script Date: 07/15/2009 08:14:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spPersonRelationshipAddOpposing]
@ExistingRelationshipID INT 
AS
BEGIN
--Declare local variables
DECLARE @PersonID INT  --PersonID of established relarionship
DECLARE @RelatedID INT  --RelatedID of established relarionship
DECLARE @Relationship VARCHAR(4)  --Established relarionship
DECLARE @RelatedSex as VARCHAR(1)  
DECLARE @OpposingRelationship VARCHAR(4)
DECLARE @OpposingRelationshipID INT
--Fill variables from existing relationship
SELECT @PersonID = PersonID, @RelatedID = RelatedID, @Relationship=PersonRelationshipTypeID
FROM tblPersonRelationship where PersonRelationshipID = @ExistingRelationshipID
--Get gender of relative for finding opposing relationship type
SELECT @RelatedSex = (SELECT Gender FROM tblPerson WHERE PersonID = @PersonID)
--get opposing relationship types
IF (@RelatedSex='M')
    BEGIN
    SELECT @OpposingRelationship = (SELECT OpposingMaleRelationship 
                                    From tblAdminPersonRelationshipType 
                                    WHERE PersonRelationshipTypeID = @Relationship)
    END
ELSE IF (@RelatedSex='F')
    BEGIN
    SELECT @OpposingRelationship = (SELECT OpposingFemaleRelationship 
                                    From tblAdminPersonRelationshipType 
                                    WHERE PersonRelationshipTypeID = @Relationship)
    END
--check for existing opposing relationship
SELECT @OpposingRelationshipID = (SELECT MAX(PersonRelationshipID) FROM tblPersonRelationship WHERE PersonID = @RelatedID AND RelatedID = @PersonID)
--if an opposing relationship was found

IF (@OpposingRelationship IS NOT NULL)
    BEGIN
--if there is a relationship, update it
    IF ISNUMERIC(@OpposingRelationshipID)=1 
        BEGIN
            UPDATE tblPersonRelationship
            SET PersonRelationshipTypeID = @OpposingRelationship,
                MarriageDate = (SELECT MarriageDate FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID),
                ResidesWithPersonFlag = (SELECT ResidesWithPersonFlag FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID),
                UpdateDateTime = (SELECT UpdateDateTime FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID),
                UpdateProgram = (SELECT UpdateProgram FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID),
                UpdateUserID = (SELECT UpdateUserID FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID) 
            WHERE PersonRelationshipID = @OpposingRelationshipID
        END
--otherwise add record
    ELSE IF (@OpposingRelationship IS NOT NULL)
        BEGIN
            INSERT INTO tblPersonRelationship 
                SELECT @RelatedID, @OpposingRelationship, @PersonID,
                       MarriageDate, NULL, NULL, 
                       ResidesWithPersonFlag, NULL, UpdateDateTime, UpdateProgram,
                       UpdateUserID, UpdateDateTime, UpdateProgram, 
                       UpdateUserID, NULL FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID
        END
    END
END

6 个答案:

答案 0 :(得分:11)

执行INSERT时,应始终明确指定列的列表。 像这样重写你的代码:

INSERT INTO tblPersonRelationship (RelatedID, PersonRelationshipID, PersonID, ...)
SELECT @RelatedID, @OpposingRelationship, @PersonID, ...

隐式添加了一个guid列以支持合并复制,这就是您收到列列表不匹配错误的原因。

答案 1 :(得分:2)

当INSERT操作期间,当提供的列名数或提供的值数与表定义不匹配时,将显示此错误消息(插入错误:列名或提供的值数与表定义不匹配)。 / p>

我认为你正在处理后者 - 提供的值的数量与表定义不匹配。这是我的预感,因为你注意到一个rowguid列已添加到一个你的桌子。

让我们将你的插入转换为tblPersonRelationship,例如。基于SELECT,应该假设tblPersonRelationship有15个非默认列。如果添加了rowguid列,则现在需要在SELECT中以正确的位置表示。

INSERT INTO tblPersonRelationship                 
SELECT 
@RelatedID, @OpposingRelationship, @PersonID,                       
MarriageDate, NULL, NULL,                        
ResidesWithPersonFlag, NULL, UpdateDateTime, 
UpdateProgram, UpdateUserID, UpdateDateTime, 
UpdateProgram, UpdateUserID, NULL,
newid()  
FROM tblPersonRelationship 
WHERE PersonRelationshipID = @ExistingRelationshipID     

处理计算列时,您也可能会收到此错误。我不相信这是你的问题,但你可以find more here

答案 2 :(得分:1)

我知道你可能需要从发布者“推送”架构更改,而不是尝试从客户端提取它们。

通过此处的联机丛书说明,按照修改特定复制拓扑的文章的过程进行操作:

http://msdn.microsoft.com/en-us/library/ms152493(SQL.90).aspx

让我知道你是怎么过的。

答案 3 :(得分:1)

在程序的最后,您有以下INSERT:

    INSERT INTO tblPersonRelationship 
        SELECT @RelatedID, @OpposingRelationship, @PersonID,
               MarriageDate, NULL, NULL, 
               ResidesWithPersonFlag, NULL, UpdateDateTime, UpdateProgram,
               UpdateUserID, UpdateDateTime, UpdateProgram, 
               UpdateUserID, NULL FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID

如果再向tblPersonRelationship添加一列,此代码将中断。因此,您需要使用以下代码替换此代码:

    INSERT INTO tblPersonRelationship(explicit list of columns you are providing values for)
        SELECT @RelatedID, @OpposingRelationship, @PersonID,
               MarriageDate, NULL, NULL, 
               ResidesWithPersonFlag, NULL, UpdateDateTime, UpdateProgram,
               UpdateUserID, UpdateDateTime, UpdateProgram, 
               UpdateUserID, NULL FROM tblPersonRelationship WHERE PersonRelationshipID = @ExistingRelationshipID

by“您为其提供值的列的列表”我指的是SELECT中的值列表:

@RelatedID, @OpposingRelationship, @PersonID,
               MarriageDate, NULL, NULL, 
               ResidesWithPersonFlag, NULL, UpdateDateTime, UpdateProgram,
               UpdateUserID, UpdateDateTime, UpdateProgram, 
               UpdateUserID, NULL

因为您没有为rowguid提供值,所以不要将它包含在列列表中。

答案 4 :(得分:1)

继续您的其他(已删除)问题,让我们剖析该错误消息:

  

列名或提供的值与表定义不匹配。

我检查了insert语句两边的值的数量,它们是匹配的,所以不是这样。并且sql server不关心VALUES列表中的列名,所以不是这样。这意味着INSERT列表中的一个列名称是错误的。那里你有很多名字 - 你有没有检查过某个地方没有错字?

答案 5 :(得分:0)

Guid专栏的

scope_identity()?不,你需要做更多的工作来获得新的指导。

首先,您必须创建一个表变量:

DECLARE @outputIdTbl TABLE (ID uniqueidentifier)

然后你必须将它放在insert语句的中间。

INSERT INTO [dbo].[Orders]
           ([AccountId]
           ,[InvoiceDate]
           ,[LastUpdate]
           ,[UserId]
           ,[Sent]
          ,IsCredit
           ,[Status]
          ,Note2)
    output INSERTED.id into @outputIdTbl 
    VALUES
           (@AccountId
           ,@InvoiceDate
           ,GetDate()
           ,@UserId
           ,@Sent
          ,@IsCredit
           ,@Status
          ,@Note2)

然后您可以从表变量中检索值。

select @OrderId = id from @outputIdTbl