Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Ошибка при выполнении хранимой процедуры


Автор: thomas 20.12.2007, 18:06
Приветствую всех.
Написал хранимую процедуру для вставки строки с данными на товар. Время записи должно подставляться автоматически на стороне сервера.
Код

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[usp_Artikel_Add]
    @subCategorieId INT,
    @artikelNaam NVARCHAR(50), 
    @omschrijving NVARCHAR(150),
    @eenheid NCHAR(4),
    @minVoorraad INT,
    @voorraad INT,
    @winst INT,
    @huidigePrijs MONEY,
    @artikelId INT OUTPUT
AS
BEGIN
    DECLARE @modifiedDate DATETIME;
    SET @modifiedDate = GETDATE();
    INSERT INTO tblArtikel
        (
        ArtikelId,
        SubCategorieId,
        ArtikelNaam, 
        Omschrijving,
        Eenheid,
        MinVoorraad,
        Voorraad,
        Winst,
        HuidigePrijs,
        ModifiedDate
        )
    VALUES
        (
        @artikelId,
        @subCategorieId,
        @artikelNaam, 
        @omschrijving,
        @eenheid,
        @minVoorraad,
        @voorraad,
        @winst,
        @huidigePrijs,
        @modifiedDate
        )
    SELECT @artikelId = SCOPE_IDENTITY()
END

При проверке синтаксиса managemant studio не ругается, но если попробовать выполнить эту ХП, то получаю вот эту ошибку.
Цитата

Must pass parameter number 9 and subsequent parameters as '@name = value'. After the form '@name = value' has been used, all subsequent parameters must be passed in the form '@name = value'.


Знаю, что слон где-то рядом, но не вижу его!  smile 

Подскажите в чем может быть проблема, где собственно грабли, что я сделал не так?
Или пните в нужном направлении.  smile 
Заранее благодарю.

Добавлено @ 18:11
ЗЫ и извините я с англицким не очень дружу, потому не соображу как понять это сообщение. А язык который я понимаю студия не использует.  smile 

Автор: skyboy 20.12.2007, 18:29
Цитата(thomas @  20.12.2007,  17:06 Найти цитируемый пост)
Знаю, что слон где-то рядом, но не вижу его

мы тоже не увидим. пока не приведешь вызывающий ХП код. ведь сам сказал:
Цитата(thomas @  20.12.2007,  17:06 Найти цитируемый пост)
При проверке синтаксиса managemant studio не ругается, но если попробовать выполнить эту ХП, то получаю вот эту ошибку.

а вызывающий код не привел...

Добавлено через 1 минуту и 57 секунд
Цитата(thomas @  20.12.2007,  17:06 Найти цитируемый пост)
 After the form '@name = value' has been used, all subsequent parameters must be passed in the form '@name = value'.

наверное, ты при вызове процедуры не просто передаешь параметры, а используешь форму "@имя=значение", что позволяет тебе менять порядок передачи параметров, так как ты явно указываешь имя. правильно? так и вызываешь?
а СУБД тебе говорит, что если передаешь хоть один параметр с явным указанием имени параметра, остальные 9 должны быть переданы в том же стиле.

Добавлено через 2 минуты и 35 секунд
Цитата(skyboy @  20.12.2007,  17:29 Найти цитируемый пост)
all subsequent

Цитата(skyboy @  20.12.2007,  17:29 Найти цитируемый пост)
остальные 9 должны быть переданы в том же стиле

точнее сказать, "все последующие параметры должны быть переданы в той же форме"

Автор: thomas 20.12.2007, 18:47
skyboy, 
Цитата

а вызывающий код не привел...

Так я ее родимую в самой студии и пытаюсь выполнить. Жму правой кнопкой мыша на имя ХП и выбираю "Выполнить хранимую процедуру ..."
Появляется окошко для ввода параметров,ввожу параметры, кроме последнего artikelId, так как ХП должна присвоить значение ему и вернуть. Поле с автонумерацией.
Жму ОК и получаю сообщение об ошибке и вот это вместо ХП
Код

USE [VKL]
GO

DECLARE    @return_value int,
        @artikelId int

EXEC    @return_value = [dbo].[usp_Artikel_Add]
        @subCategorieId = 1,
        @artikelNaam = N'test3',
        @omschrijving = N'artikel nummer drie',
        @eenheid = N'stuk',
        @minVoorraad = 10,
        @voorraad = 100,
        @winst = 20,
        @huidigePrijs = 3,62,
        @artikelId = @artikelId OUTPUT

SELECT    @artikelId as N'@artikelId'

SELECT    'Return Value' = @return_value

GO

До кода в приложении еще далеко.

Добавлено через 4 минуты и 34 секунды
Слушай, а может засада в том что полей в таблице 10, а задается 9-ть параметров перед AS.
И последний modifiedDate задается в DECLARE

Автор: skyboy 20.12.2007, 18:53
видимо, потому что 
Цитата(thomas @  20.12.2007,  17:47 Найти цитируемый пост)
 @huidigePrijs = 3,62,

воспринимается не как один параметр со значением "3.62", а два параметра: huidigePrijs со значением "3" и неименованный параметр "62". впрочем, могу ошибаться. 

Автор: thomas 20.12.2007, 19:08
skyboy, 
Цитата

Знаю, что слон где-то рядом, но не вижу его!

Действительно, а слона то я и не заметил.  smile 
Спасибо.  smile 

Но там еще был один нюанс.
Нельзя писать в INSERT INTO имя поля ArtikelId и в VALUES имя параметра @artikelId. Id строке приваивается в результате выполнения ХП и его же она возвращает.
Вот код работающей ХП
Код

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
      
ALTER PROCEDURE [dbo].[usp_Artikel_Add]
    @subCategorieId INT,
    @artikelNaam NVARCHAR(50), 
    @omschrijving NVARCHAR(150),
    @eenheid NCHAR(4),
    @minVoorraad INT,
    @voorraad INT,
    @winst INT,
    @huidigePrijs MONEY,
    @artikelId INT OUTPUT
AS
BEGIN
    DECLARE @modifiedDate DATETIME;
    SET @modifiedDate = GETDATE();
    INSERT INTO tblArtikel
        (
        SubCategorieId,
        ArtikelNaam, 
        Omschrijving,
        Eenheid,
        MinVoorraad,
        Voorraad,
        Winst,
        HuidigePrijs,
        ModifiedDate
        )
    VALUES
        (
        @subCategorieId,
        @artikelNaam, 
        @omschrijving,
        @eenheid,
        @minVoorraad,
        @voorraad,
        @winst,
        @huidigePrijs,
        @modifiedDate
        )
    SELECT @artikelId = SCOPE_IDENTITY()
END


Можем двигаться дальше  smile  smile  smile 

Автор: skyboy 20.12.2007, 20:13
Цитата(thomas @  20.12.2007,  18:08 Найти цитируемый пост)
Нельзя писать в INSERT INTO имя поля ArtikelId и в VALUES имя параметра @artikelId. Id строке приваивается в результате выполнения ХП и его же она выполняет.

в смысле - поле было типа idenity? так если не стоит "not for replication", то должно, как мне кажется, поддерживать "ручную" вставку значения. прошу сообщить, если я ошибаюсь.

Автор: thomas 21.12.2007, 00:26
skyboy, 

Там в цитате ошибочка, я когда писал пост описался: вместо выполняет ==> возвращает.

Поле ArtikelId является РК и в свойствах выставлено "Является идентифицирующим столбцом" - ДА
"Не для репликации" установлено НЕТ.

Попробовал в студии в открытую таблицу вставить новую строку и при этом указать ArtikelId в ручную.
Не получилось. 
В пустой строке все ячейки NULL, встал на первую жму клавишу цифры и нифига. В остальные поля данные заносятся на ура.
Перешёл на следующую строку, та которая была заполнена получила ArtikelId на номер больший предыдущего (1,2,3,5)

Не знаю это ли ты подразумевал под 
Цитата

"ручную" вставку значения

Автор: skyboy 21.12.2007, 00:35
thomas, да, это. 
я считал, что если not for replication: false, то как раз можно вставлять значения вручную.
но ошибся, надо было сразу в ман заглянуть.
Цитата

The NOT FOR REPLICATION option allows you to specify that the following database objects are treated differently when a replication agent performs an operation:
[...]
- The identity column value is not incremented when a replication agent performs an insert operation.

т.е. при not for replication: true значение последнего вставленного identity не увеличивается при вставке новой записи в процессе репликации.

Добавлено через 7 минут и 15 секунд
черт, ведь крутилось в голове ведь...
чтоб можно было "вручную вставлять" значения в identity-поле необходимо "вручную заявить" про это желание при помощи http://technet.microsoft.com/en-us/library/ms188059.aspx типа
Код

SET identity_insert <tabename> ON

до insert'a и "выключения"(то же самое, но вместо "ON" - "OFF") вставки после insert'a

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)