2009-06-09 3 views
1

Я добавил щедрость к этому, так как у меня есть, что до сих пор было в состоянии понять это, и время ушло.Добавление столбца rowguid нарушило эту хранимую процедуру?


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

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 был создан для слияния 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 
+0

Вы получаете сообщение об ошибке, когда пытаетесь его воспроизвести? Разве это просто не появляется? –

+0

Извините, после вашего комментария я понял, как дерьмовый вопрос был, и я переформулировал его. Это лучше? –

+0

Этот вопрос был переработан, чтобы попытаться атаковать это под другим углом. Я приспосабливаюсь к двум плакатам ниже, так как это делает должности неуместными, но это было необходимо, поскольку они не отвечали на мой вопрос и даже с щедростью, которую никто больше не пытался. –

ответ

11

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

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

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

+0

Вы также явно указываете столбцы с значениями по умолчанию? –

+4

Нет, вам не нужно явно указывать столбцы со значениями по умолчанию, так как SQL по умолчанию будет иметь значение. Однако убедитесь, что вы не указываете столбец IDENTITY, который имеет автоинкремент. –

+1

Вам не нужно указывать столбцы со значениями по умолчанию, если вы не добавляете значение для этого столбца. – BinaryMisfit

1

Я bleieve вам, возможно, придется «PUSH» изменения схемы от издателя, а не пытаться тянуть их от клиента.

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

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

Позвольте мне знать, как вы получите на.

+0

Хмм, спасибо за сообщение, и я прочитаю вашу ссылку. Я немного обеспокоен тем, что переключился на схему Push, так как мое приложение - это «определенное время», связанное с CRUD-приложением, которое не связано ни с одним установленным графиком. –

+0

Это приятное чтение, но в зависимости от нашей ситуации и этой должности здесь -> http://stackoverflow.com/questions/748848/should-i-use-a-push-or-pull-subscription-if-using- rmo Использование Push вместо Pull - плохая идея. Мысли? –

0

Вы копируете все таблицы и представления, на которые ссылается хранимая процедура?

+0

Да, я копирую все доступные статьи. –

2

Это сообщение об ошибке (Ошибка вставки: имя столбца или количество заданных значений не соответствует определению таблицы) появляется во время операции 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  

Вы также можете получить эту ошибку при работе с вычисленными столбцами. Я не считаю, что это ваша проблема, но вы можете find more here.

+0

Спасибо, Я попытался добавить ключевое слово DEFAULT, где вы поместили GUID VALUE, но теперь я получил неверную ошибку синтаксиса. Я посмотрел на некоторые другие SProcs, и они имеют DEFAULT, перечисленные для значения rowguid, поэтому я смущен тем, что я делаю неправильно. –

+1

Возможно, я был неясно в своем ответе. Вам не нужно беспокоиться о дефолтах обязательно. Если вам просто нужен GUID для генерации, используйте newid(). Я также обновил запрос. –

+0

Нет, я думал, тебе ясно. Мне нужно было предоставить значение для всех столбцов. Моя путаница, я думаю, связана с тем фактом, что в Sister Query на одном DB значение, заданное для rowguid, равно DEFAULT. Использование newid() работает, хотя так спасибо. –

1

Don't write stored procedures...

я получу свое пальто.

+0

Считаете ли вы, что это полезно или с чувством юмора? Просто проверяя, поэтому я не трачу свое время прямо сейчас. –

+1

Честно говоря, оба. Я согласен на 100% с Джеффом, что Хранимые процедуры больше не являются правильным ответом. Если у вас уже есть бизнес-уровень, просто держите * все * от логики. Ваша жизнь будет лучше для этого. С другой стороны, я понимаю, что мой комментарий кажется забавным и бесполезным, и я извиняюсь за мыльный бокс в вашем вопросе. –

+0

Сумасшедшие ошибки, такие как те, которые вы получаете, являются лишь номинальными для курса в Хранимых процедурах. –

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 

по «списку столбцов предоставляют значения» Я имею в виду список значений в вашем SELECT:

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

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

+0

Вы заявляете, что мне нужен явный список столбцов, для которого я предоставляю значение. Означает ли это, поскольку rowguid имеет значение по умолчанию newsequentialid(), что мне не нужно перечислять rowguid? –

+0

Я добавил ответ на ваш комментарий в теле моего первоначального ответа –

1

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

Column name or number of supplied values does not match table definition.

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

+0

:-) Ваш быстрый (+1), я удалил это, как только понял свою ошибку. Ошибка в удаленной записи заключалась в том, что я указывал, что строка #, указанная в ошибке, была точной, когда она, по сути, не является. Как только я понял это, я понял, что мой вопрос был еще ниже SProc (не в должности), поскольку то, что я перечислил, зафиксировал эту часть. –

0

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