执行存储过程一个参数太少,两个参数太多

时间:2019-03-07 12:44:09

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

我有这样的程序

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 :(得分:0)

缺少(),这是添加要插入的列名的好策略

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

答案 1 :(得分:0)

我没问题运行它:

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

您现在在表中有此结果。您可以在过程的末尾编写一条select语句,或者因为您确定只插入一条记录,所以可以声明一个@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关键字以及参数名称和变量的键-值对(您应始终使用这种方式来调用过程)。

尝试一下再回来!