ExecuteSqlCommand с выходным параметром

Я использую Entity Framework в приложении ASP.NET MVC3, и я пытаюсь использовать следующий код:

var token = "";
this.Database.ExecuteSqlCommand("exec dbo.MyUsp", new SqlParameter("token", token));

Моя сохраненная сигнатура proc:

CREATE PROCEDURE MyUSP(@token varchar(10) OUT)
(...)

Когда я использую этот код, я получаю сообщение об ошибке, указывающее, что параметр "@token" ожидался, но не был указан.

Как сообщить EF, что параметр токена для вывода?

Ответ 1

Я закончил использовать это, чтобы заставить его работать, но я уверен, что есть более оптимальный способ:

var p = new SqlParameter
{
    ParameterName = "token",
    DbType = System.Data.DbType.String,
    Size = 100,
    Direction = System.Data.ParameterDirection.Output
};
var resp = this.Database.SqlQuery<String>("exec dbo.usp_GetRequestToken @token", p);

return resp.First();

Ответ 2

var outParam = new SqlParameter();
outParam.ParameterName = "OutPutParametname";
outParam.SqlDbType = SqlDbType.Bit;//DataType Of OutPut Parameter
outParam.Direction = ParameterDirection.Output;
db.Database.ExecuteSqlCommand("EXEC ProcedureName @Param1,@Param2[This is for output]                   OUTPUT", new SqlParameter("Param1", value), outParam);
object outParamValue = Convert.ToBoolean(outParam.Value);

Ответ 3

Вам нужно указать направление в параметре. Например, попробуйте что-то вроде этого:

var p = new SqlParameter("token", token);
p.Direction = ParameterDirection.InputOutput;
this.Database.ExecuteSqlCommand("exec dbo.MyUsp", p);

Ответ 4

Я решил эту проблему следующим кодом SQL и Entity Framework

SP:

    ALTER PROCEDURE [dbo].[SaveSingleColumnValueFromGrid]
(
    @TableName VARCHAR(200),
    @ColumnName VARCHAR (200),
    @CompareField VARCHAR(200),
    @CompareValue VARCHAR(200),
    @NewValue VARCHAR(200),
    @Result INT OUTPUT
)
AS
BEGIN
    DECLARE @SqlString NVARCHAR(2000),
            @id INTEGER = 0;


    IF @CompareValue = ''
        BEGIN

            SET @SqlString = 'INSERT INTO ' + @TableName + ' ( ' + @ColumnName +  ' )  VALUES ( ''' + @NewValue + ''' ) ; SELECT @id = SCOPE_IDENTITY()';
            EXECUTE sp_executesql @SqlString, N'@id INTEGER OUTPUT',  @id OUTPUT
        END
    ELSE
        BEGIN
            SET @SqlString = 'UPDATE ' + @TableName + ' SET ' + @ColumnName +  ' = ''' + @NewValue + '''  WHERE ' + @CompareField +  ' = ''' + @CompareValue + '''';
            EXECUTE sp_executesql @SqlString
            set @id = @@ROWCOUNT
        END


    SELECT @Result = @id
END

Код структуры Entity:

public FieldUpdateResult SaveSingleColumnValueFromGrid(string tableName, string tableSetFieldName, string updatedValue, string tableCompareFieldName, string uniqueFieldValue)
        {

            var fieldUpdateResult = new FieldUpdateResult() ;
            var isNewRecord = false;

            if (string.IsNullOrWhiteSpace(uniqueFieldValue))
            {
                uniqueFieldValue = string.Empty;
                isNewRecord = true;
            }
            using (var dbContext = new DBEntities())
            {
                var resultParameter = new SqlParameter("@Result", SqlDbType.Int)
                {
                    Direction = ParameterDirection.Output
                };

                var recordsAffected = dbContext.Database.ExecuteSqlCommand("SaveSingleColumnValueFromGrid @TableName,@ColumnName,@CompareField,@CompareValue,@NewValue,@Result out",
                    new SqlParameter("@TableName", tableName),
                    new SqlParameter("@ColumnName", tableSetFieldName),
                    new SqlParameter("@CompareField", tableCompareFieldName),
                    new SqlParameter("@CompareValue", uniqueFieldValue),
                    new SqlParameter("@NewValue", updatedValue),
                    resultParameter);

                fieldUpdateResult.Success = recordsAffected > 0;
                if (isNewRecord)
                {
                    fieldUpdateResult.NewId = (int)resultParameter.Value;
                }
                else
                {
                    fieldUpdateResult.AffectedRows = (int)resultParameter.Value;
                }
            }

            return fieldUpdateResult;
        }

Ответ 5

Ниже приводится то, что я делаю для Oracle, используя драйвер DevArt. У меня есть package.proc, называемый P_SID.SID_PGet, который возвращает одно строковое значение. Прок:

PROCEDURE SID_PGet(io_SID OUT varchar2) is
Begin
   io_SID:=GetSID; -- GetSID just goes off and gets the actual value
End;

Ниже описано, как я его вызываю и извлекаю значение SID (сначала я использую это с кодом EF 4.1, и этот метод находится в DbContext):

/// <summary>
/// Get the next SID value from the database
/// </summary>
/// <returns>String in X12345 format</returns>
public string GetNextSId()
{
    var parameter = new Devart.Data.Oracle.OracleParameter("io_SID", Devart.Data.Oracle.OracleDbType.VarChar, ParameterDirection.Output);
    this.Database.ExecuteSqlCommand("BEGIN P_SID.SID_PGet(:io_SID); END;", parameter);
    var sid = parameter.Value as string;

    return sid;
}

Ответ 6

var db = new DBContext();
var outParam = new SqlParameter
{
    ParameterName = "@Param",
    DbType = System.Data.DbType.String,
    Size = 20,
    Direction = System.Data.ParameterDirection.Output
};
var r = db.Database.ExecuteSqlCommand("EXEC MyStoredProd @Param OUT",outParam );
Console.WriteLine(outParam.Value);

Основная часть, которую я вижу, что все отсутствуют, это ключевое слово OUT, необходимое после @Param.