【问题标题】:Return newly created stored procedure C#返回新创建的存储过程 C#
【发布时间】:2020-08-09 07:21:54
【问题描述】:

我尝试了两种不同的想法来解决这个问题,但没有成功。我查看了以下链接 hereherehere 但我最终得到了

对象引用未设置为对象的实例。

过程或函数 InsertHero 指定的参数过多。

当我在 SSMS 中执行存储过程时,我的 ID 也显示为关闭,因为它们从 1110 而不是设置为 100 的原始数字递增(这可能是一个不同的问题)。

似乎我已经完成了 99% 的工作,但我错过了一小部分。我错过了什么?

C#:

using (SqlConnection connection = new SqlConnection(ConnectionString))
{
    connection.Open();

    using (SqlCommand command = new SqlCommand("InsertHero", connection))
    {
        command.CommandType = CommandType.StoredProcedure;

        command.Parameters.AddWithValue("@Name", hero.Name);
        command.Parameters.AddWithValue("@Universe", hero.Universe);
        // command.Parameters.Add("@Created_Id", SqlDbType.Int).Direction = ParameterDirection.Output;

        int id = (int)command.ExecuteScalar();
    }
}

存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[InsertHero] 
    @Name nvarchar(50), 
    @Universe nvarchar(15), 
    @Created_Id int OUTPUT
AS
    INSERT INTO Hero
    VALUES (@Name, @Universe);

    SET @Created_Id = SCOPE_IDENTITY()
GO

存储过程(不同的方式):

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[InsertHero] 
    @Name nvarchar(50), 
    @Universe nvarchar(15) OUTPUT
AS
    INSERT INTO Hero
    OUTPUT inserted.Id
    VALUES (@Name, @Universe);
GO

编辑:

把这个留在这里,以防有人偶然发现它。原来是连接字符串有问题,所以一定要双重检查,也许三重检查

【问题讨论】:

标签: c# sql-server tsql stored-procedures


【解决方案1】:

第一个示例中不需要@CreatedID 参数。只需将您的存储过程更改为

ALTER procedure [dbo].[InsertHero] @Name nvarchar(50), @Universe nvarchar(15)
as
   Insert into Hero  values (@Name, @Universe);
   SELECT SCOPE_IDENTITY()

当您调用 ExecuteScalar 时,结果应该是 SELECT 语句的返回值,而不是输出参数的返回值。如果要使用输出参数,则需要将其添加到 SqlCommand 参数集合中,并在执行命令后从同一集合中读回其值。

也不要使用 AddWithValue,虽然这种方法很方便,但在 Can we Stop using AddWithValue AlreadyHow data access code affects Database performances 中记录了许多缺点

改为使用Add指定类型和大小两个参数

using (SqlConnection connection = new SqlConnection(ConnectionString))
{
    connection.Open();
    using (SqlCommand command = new SqlCommand("InsertHero", connection))
    {
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add("@Name", SqlDbType.NVarChar, 50).Value = hero.Name;
        command.Parameters.Add("@Universe", SqlDbType.NVarChar, 15).Value = hero.Universe;
        int id = (int)command.ExecuteScalar();
    }
}

如果您将@Universe 参数改回与第一个示例相同的定义(无输出子句),则第二种方法应该也能正常工作。

ALTER procedure [dbo].[InsertHero] @Name nvarchar(50), @Universe nvarchar(15)

【讨论】:

  • 感谢您的回复。奇怪的是,我仍然看到“对象引用未设置为对象的实例”。会不会有其他的影响?另外,感谢关​​于 AddWithValues 的文章。每天学习新东西
  • 你在哪一行得到这个错误?上面的 C# 代码似乎是正确的,除非变量 hero 本身为 null
  • 添加了另一篇文章,解释了有关 AddWithValue 不良性质的另一个重要细节
  • 错误 --> 将 ExecuteScalar 的结果赋值给 id
  • 你检查数据是否插入了吗?
猜你喜欢
  • 2021-11-28
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多