При выполнении хранимой процедуры один аргумент слишком мал, два - слишком много - PullRequest
0 голосов
/ 07 марта 2019

У меня есть такая процедура

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[INSERT_MessageOwner]
    @ownertype AS INT,
    @ownertenant AS INT
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO ADMINROTAS.dbo.MessageOwner
    OUTPUT Inserted.MessageOwnerID
    VALUES (@ownertype, @ownertenant);
END

Если я вызываю эту процедуру следующим образом:

DECLARE @messageOwnerType INT;
SET @messageOwnerType = 3;
...
EXECUTE [ADMINROTAS].[dbo].INSERT_MessageOwner @messageOwnerType
...

Я получаю

Процедура или функция 'INSERT_MessageOwner 'ожидает параметр' @ownertenant ', который не был предоставлен.

Если я назову это так:

DECLARE @messageOwnerType INT;
DECLARE @messageOwnerDB INT;
SET @messageOwnerType = 3;
SET @messageOwnerDB = DB_ID();
...

EXECUTE [ADMINROTAS].[dbo].INSERT_MessageOwner @messageOwnerType, @messageOwnerDB
...

Я получу

В процедуре или функции INSERT_MessageOwner указано слишком много аргументов.

Кто-нибудь знает, что здесь происходит?Я полагаю, что это может быть связано с предложением OUTPUT, но мне трудно разобраться в этом или найти правильное учение.

Я был бы очень признателен, если бы кто-то мог поставить меня на фото.Сказав все это, есть ли что-то не так с этим сообщением об ошибке?Вы прекратили спор!Добавить один.Теперь у вас их слишком много!

В качестве дополнения, я был бы очень признателен, если бы вы помогли мне понять, как получить результаты хранимой процедуры в переменную.Эта хранимая процедура сработала в JDBC, но теперь я хочу использовать ее с T-SQL.

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

У меня нет проблем с запуском этого:

CREATE DATABASE ADMINROTAS

GO

CREATE TABLE ADMINROTAS.dbo.MessageOwner
(
    MessageOwnerID INT IDENTITY PRIMARY KEY,
    ownertype INT, 
    ownertenant INT
)

GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[INSERT_MessageOwner]
    @ownertype AS INT,
    @ownertenant AS INT
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO ADMINROTAS.dbo.MessageOwner
    OUTPUT Inserted.MessageOwnerID
    VALUES (@ownertype, @ownertenant);
END

GO

DECLARE @messageOwnerType INT;
SET @messageOwnerType = 3;
EXECUTE [ADMINROTAS].[dbo].INSERT_MessageOwner @messageOwnerType

GO

DECLARE @messageOwnerType INT;
DECLARE @messageOwnerDB INT;
SET @messageOwnerType = 3;
SET @messageOwnerDB = DB_ID();

EXECUTE [ADMINROTAS].[dbo].INSERT_MessageOwner @messageOwnerType, @messageOwnerDB

Может быть, вы что-то упустили при написании вопроса. Я полагаю, что MessageOwnerID является столбцом идентификации вашей таблицы. Чтобы получить это значение, сначала нужно объявить переменную таблицы, например @Temp, со структурой столбца, который вы хотите вывести из вставки:

DECLARE @Temp TABLE
( 
    MessageOwnerID INT
)

Во-вторых, вам нужно изменить оператор OUTPUT, чтобы вставить этот результат в переменную:

OUTPUT Inserted.MessageOwnerID INTO @Temp

Теперь у вас есть эти результаты в вашей таблице. Вы можете написать оператор выбора в конце вашей процедуры, или, поскольку вы уверены, что вставляете только одну запись, вы можете объявить переменную, скажем, @MessageOwnerID. Чтобы вернуть это значение вызывающей стороне, вы должны объявить его как параметр OUTPUT. Установите его значение равным значению из временной таблицы и прочитайте его при выполнении. Ваша процедура изменяется следующим образом:

ALTER PROCEDURE [dbo].[INSERT_MessageOwner]
    @ownertype AS INT,
    @ownertenant AS INT,
    @MessageOwnerID INT = NULL OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Temp TABLE
    ( 
        MessageOwnerID INT
    )

    INSERT INTO ADMINROTAS.dbo.MessageOwner
    OUTPUT Inserted.MessageOwnerID INTO @Temp
    VALUES (@ownertype, @ownertenant);

    SELECT @MessageOwnerID = MessageOwnerID FROM @Temp
END

Помните ключевое слово OUTPUT в объявлении параметра!

Вызов процедуры меняется следующим образом:

DECLARE @messageOwnerType INT;
DECLARE @messageOwnerDB INT;
DECLARE @MessageOwnerID INT;
SET @messageOwnerType = 3;
SET @messageOwnerDB = DB_ID();

EXECUTE [ADMINROTAS].[dbo].INSERT_MessageOwner @messageOwnerType, @messageOwnerDB, @MessageOwnerID = @MessageOwnerID OUTPUT
SELECT @MessageOwnerID

Кроме того, помните ключевое слово OUTPUT для всех и пару ключ-значение имени параметра и переменной (вы всегда должны использовать этот способ для вызова процедур).

Попробуй и вернись!

0 голосов
/ 07 марта 2019

несколько пропущено (), и это хорошая политика, чтобы добавить имена столбцов для вставки

ALTER PROCEDURE [dbo].[INSERT_MessageOwner] (
    @ownertype AS INT,
    @ownertenant AS INT
)
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO ADMINROTAS.dbo.MessageOwner (yourcolumn1, yourcolumn2)
    OUTPUT Inserted.MessageOwnerID
    VALUES (@ownertype, @ownertenant);
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...