Добавление столбца rowguid сломало эту хранимую процедуру? - PullRequest
1 голос
/ 09 июня 2009

Приведенная ниже хранимая процедура не позволит мне добавить ее для ее изменения. При попытке изменить его я получаю следующую ошибку ->

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

Кроме того, поскольку БД была настроена для 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 ]

11 голосов
/ 15 июля 2009

Вы всегда должны явно указывать список столбцов при выполнении INSERT. Перепишите свой код так:

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

Неявно добавлен столбец guid для поддержки репликации слиянием, поэтому вы получили ошибку о несовпадении списков столбцов.

2 голосов
/ 15 июля 2009

Это сообщение об ошибке (Ошибка вставки: имя столбца или количество предоставленных значений не соответствует определению таблицы) появляется во время операции INSERT, когда число предоставленных имен столбцов или количество предоставленных значений не соответствует определению таблицы.

Я думаю, что вы имеете дело с последним - количество предоставленных значений не соответствует определению таблицы. Это моя догадка, основанная на том факте, что вы заметили, что столбец 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     

Вы также можете получить эту ошибку при работе с вычисляемыми столбцами. Я не верю, что это ваша проблема, но вы можете найти больше здесь .

1 голос
/ 15 июля 2009

Продолжая ваш другой (удаленный) вопрос, давайте разберем это сообщение об ошибке:

Имя столбца или количество предоставленных значений не соответствует определению таблицы.

Я проверил количество значений в обеих сторонах оператора вставки, и они совпадают, так что это не так. И sql server не заботится об именах столбцов в списке VALUES, так что это не так. Это означает, что одно из имен столбцов в списке INSERT неверно. У вас там много имен & mdash; Вы проверили, что у вас нет опечатки где-нибудь?

1 голос
/ 15 июля 2009

В самом конце вашей процедуры у вас есть следующая ВСТАВКА:

    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, не включайте его в список столбцов.

1 голос
/ 09 июня 2009

Полагаю, вам может понадобиться "вытолкнуть" изменения схемы из издателя, а не пытаться извлечь их из клиента.

Следуйте процессу изменения Статьи для вашей конкретной топологии репликации из инструкции Books Online здесь:

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

Дайте мне знать, как вы поживаете.

0 голосов
/ 16 июля 2009

scope_identity () для столбца Guid? Нет, вам нужно проделать гораздо больше работы, чтобы получить новый гид.

Сначала необходимо создать переменную таблицы:

DECLARE @outputIdTbl TABLE (ID uniqueidentifier)

Затем вы должны поместить это в середину вашего оператора вставки.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...