Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF6-ExecuteSqlCommandAsync-Get返回参数(声明标量变量错误)_C#_Sql Server_Entity Framework 6 - Fatal编程技术网

C# EF6-ExecuteSqlCommandAsync-Get返回参数(声明标量变量错误)

C# EF6-ExecuteSqlCommandAsync-Get返回参数(声明标量变量错误),c#,sql-server,entity-framework-6,C#,Sql Server,Entity Framework 6,我有以下代码: object[] parameters = { new SqlParameter("@val1", val1), new SqlParameter("@val2", val2), new SqlParameter { ParameterName = "@retVal", SqlDbType = SqlDbType.Int, Directi

我有以下代码:

object[] parameters =
    {
        new SqlParameter("@val1", val1),
        new SqlParameter("@val2", val2),
        new SqlParameter
        {
            ParameterName = "@retVal",
            SqlDbType = SqlDbType.Int,
            Direction = ParameterDirection.ReturnValue,
            Value = -1
        }
    };

    await context.Database.ExecuteSqlCommandAsync("EXEC @retVal = Example_SP @val1, @val2", parameters);
我使用的SP很好,并返回SQL MS fine中的值。但当我使用EF执行它时,我被告知“必须声明标量变量@retVal”。这不是我的SqlParameter所做的吗

我曾尝试从参数中删除@符号,正如其他地方所建议的那样,但据我所知,@符号是可选的,没有任何区别

如何使用ExecuteSqlCommandAsync从SP获取返回值而不导致错误

谢谢大家!

您需要使用ParameterDirection.Output而不是ParameterDirection.ReturnValue。

理由:ExecuteSqlCommand函数返回受影响的行数。您需要一个额外的输出,即插入的“返回”id。因此,您需要提供一个输出参数,它可以保存该值

解决方案

将System.Data.ParameterDirection.Output用于NpgsqlParameter内的方向

  NpgsqlParameter idOut = new NpgsqlParameter
        {
            Direction = System.Data.ParameterDirection.Output
        };
  await _context.Database.ExecuteSqlCommandAsync($"INSERT INTO mytable (myid, create_time, modified_time) VALUES ({mytableid}, now(),now()) RETURNING myid;", idOut);

让我介绍一些扩展的解决方案

在这个工作示例中,正如您所看到的,有一个存储过程,它具有输出参数和异步/等待C代码,该代码显示了如何接受此输出单个值

我希望这将有助于理解该方法,并将是对您问题的扩展回答

C WinForm

TSQL 此SP仅按其数量的定义批量大小删除一些记录

ALTER PROCEDURE [dbo].[DeleteOldDevicePositions] 
    @MaxToDeleteInp int = 1000, -- Max amount of records to delete
    @BatchSizeInp int = 100, -- it is
    @ToEndDateInp datetime, -- Delete until this datetime
    @Records int OUTPUT  
AS
BEGIN
 
    SET NOCOUNT ON;
   
    DECLARE @MaxToDelete int ,  @BatchSize int , @ToEndDate datetime;
    SET @MaxToDelete = @MaxToDeleteInp;
    SET @BatchSize = @BatchSizeInp;
    SET @ToEndDate = @ToEndDateInp;

    DECLARE @TransactionInterval tinyint = 5, @FactDeleted int = 0;
    DECLARE @counter int = 1;
    DECLARE @s datetime, @e datetime, @r int = 1;    
    SELECT @s = MIN(AtTime) FROM dbo.DevicePositions;
    BEGIN TRANSACTION;
    WHILE (@r > 0)
    BEGIN
      IF @r % @TransactionInterval = 1
      BEGIN
        COMMIT TRANSACTION;
        BEGIN TRANSACTION;
      END
      DELETE TOP (@BatchSize) FROM DevicePositions WHERE AtTime >= @s AND AtTime <= @ToEndDate;
      SET @FactDeleted = @FactDeleted +@BatchSize;
      SET @r = @@ROWCOUNT;
      SET @counter = @counter + 1;
      IF @FactDeleted >= @MaxToDelete 
         BREAK;
    END
    IF @@TRANCOUNT > 0
    BEGIN
      COMMIT TRANSACTION;
      IF @counter % 10  = 0  -- or maybe 100 or 1000
      BEGIN 
        CHECKPOINT; 
      END
    END 
     
    SELECT @Records = A.Records FROM (
            SELECT OBJECT_NAME(object_id) as ID, SUM(row_count) AS Records FROM sys.dm_db_partition_stats WHERE 
            object_id = OBJECT_ID('DevicePositions') AND index_id < 2
            GROUP BY OBJECT_NAME(object_id) ) A 
   RETURN  @Records;
END
应用程序 在这里可以看到删除后的记录数


在您的示例中,@retVal不是一个返回值,它只是一个输出参数,碰巧被分配了SP的返回值。这个问题所需要的一切都在一个简单、尖锐、可接受的答案中说明。我不知道这段无法解释的代码会给它增加什么。
ALTER PROCEDURE [dbo].[DeleteOldDevicePositions] 
    @MaxToDeleteInp int = 1000, -- Max amount of records to delete
    @BatchSizeInp int = 100, -- it is
    @ToEndDateInp datetime, -- Delete until this datetime
    @Records int OUTPUT  
AS
BEGIN
 
    SET NOCOUNT ON;
   
    DECLARE @MaxToDelete int ,  @BatchSize int , @ToEndDate datetime;
    SET @MaxToDelete = @MaxToDeleteInp;
    SET @BatchSize = @BatchSizeInp;
    SET @ToEndDate = @ToEndDateInp;

    DECLARE @TransactionInterval tinyint = 5, @FactDeleted int = 0;
    DECLARE @counter int = 1;
    DECLARE @s datetime, @e datetime, @r int = 1;    
    SELECT @s = MIN(AtTime) FROM dbo.DevicePositions;
    BEGIN TRANSACTION;
    WHILE (@r > 0)
    BEGIN
      IF @r % @TransactionInterval = 1
      BEGIN
        COMMIT TRANSACTION;
        BEGIN TRANSACTION;
      END
      DELETE TOP (@BatchSize) FROM DevicePositions WHERE AtTime >= @s AND AtTime <= @ToEndDate;
      SET @FactDeleted = @FactDeleted +@BatchSize;
      SET @r = @@ROWCOUNT;
      SET @counter = @counter + 1;
      IF @FactDeleted >= @MaxToDelete 
         BREAK;
    END
    IF @@TRANCOUNT > 0
    BEGIN
      COMMIT TRANSACTION;
      IF @counter % 10  = 0  -- or maybe 100 or 1000
      BEGIN 
        CHECKPOINT; 
      END
    END 
     
    SELECT @Records = A.Records FROM (
            SELECT OBJECT_NAME(object_id) as ID, SUM(row_count) AS Records FROM sys.dm_db_partition_stats WHERE 
            object_id = OBJECT_ID('DevicePositions') AND index_id < 2
            GROUP BY OBJECT_NAME(object_id) ) A 
   RETURN  @Records;
END