【问题标题】:Executing stored procedure one argument is too few, two is too many执行存储过程一参数太少,二太多
【发布时间】:2019-07-29 08:36:19
【问题描述】:

我有这样的程序

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 中使用它。

非常感谢。

【问题讨论】:

  • 有什么更新吗?你试过什么吗?

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


【解决方案1】:

很少缺少 (),添加列名以进行插入是个好策略

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

【讨论】:

    【解决方案2】:

    我运行这个没有问题:

    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
    

    另外,请记住 all 上的 OUTPUT 关键字以及参数名称和变量的键值对(您应该始终使用这种方式调用过程)。

    试一试,然后回来!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多