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

问题描述 投票:0回答:2

我有这样的程序

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
2个回答
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

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

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

试试看吧!

© www.soinside.com 2019 - 2024. All rights reserved.