C# 插入行的返回值

C# 插入行的返回值,c#,sql-server,winforms,C#,Sql Server,Winforms,我需要返回插入记录的值,以传递给代码以打开表单。如何获得该值?下面的代码添加记录并刷新datagridview System.Data.SqlClient.SqlConnection sqlConnection1 = new System.Data.SqlClient.SqlConnection("Data Source=***.**.***.**,****;Initial Catalog=newCityCollection_Aracor;Persist Sec

我需要返回插入记录的值,以传递给代码以打开表单。如何获得该值?下面的代码添加记录并刷新datagridview

System.Data.SqlClient.SqlConnection sqlConnection1 =
                 new System.Data.SqlClient.SqlConnection("Data Source=***.**.***.**,****;Initial Catalog=newCityCollection_Aracor;Persist Security Info=True;User ID=4456r;Password=654935749653");

System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "INSERT PropertyInformation (ClientKey) VALUES (1)";
cmd.Connection = sqlConnection1;

sqlConnection1.Open();
cmd.ExecuteNonQuery();
sqlConnection1.Close();

this.propertyInformationDataGridView.Invalidate();
this.propertyInformationDataGridView.EndEdit();
this.propertyInformationDataGridView.Refresh();
this.newCityCollectionDataSet.AcceptChanges();
this.propertyInformationTableAdapter.Fill(newCityCollectionDataSet.PropertyInformation); 

将SQL更改为类似以下内容:

INSERT PropertyInformation (ClientKey) VALUES (1);
SELECT * FROM PropertyInformation WHERE RecordID = scope_identity()

scope_identity应为您提供当前会话的最后一个插入的标识列记录ID,该ID将是您刚刚插入PropertyInformation的行的ID。

将SQL更改为类似以下内容:

INSERT PropertyInformation (ClientKey) VALUES (1);
SELECT * FROM PropertyInformation WHERE RecordID = scope_identity()

scope_identity应为您提供当前会话的最后一个插入的标识列记录ID,该ID将是您刚刚插入PropertyInformation的行的ID。

我建议您将此类操作包装到存储过程中。让它将新记录的ID作为OUT变量返回

…然后可以在SqlCommand的Parameters属性中检索OUT参数。就我个人而言,我喜欢用一种方法来包装它;以下是我使用参数同步执行存储过程的方法,稍微简化:

public static Dictionary<string, object>  ExecSproc(string connectionString, string proc, IEnumerable<SqlParameter> parameters)
    {
    SqlCommand  command = null;
    try
        {
        SqlConnection  connection = GetConnection(connectionString);

        // Build the command
        command                = new SqlCommand(proc, connection);
        command.CommandTimeout = TimeOutSeconds;
        command.CommandType    = CommandType.StoredProcedure;

        // Append parameters
        SqlParameter  retValue = new SqlParameter("Return value", null);
        retValue.Direction = ParameterDirection.ReturnValue;
        command.Parameters.Add(retValue);
        if (parameters != null)
            foreach (SqlParameter param in parameters)
                command.Parameters.Add(param);

        // GO GO GO!
        command.ExecuteNonQuery();

        // Collect the return value and out parameters
        var  outputs = new Dictionary<string, object>();
        foreach (SqlParameter param in command.Parameters)
            if (param.Direction != ParameterDirection.Input)
                outputs.Add(param.ParameterName, param.Value);
        return outputs;
        }
    finally
        {
        if (command != null)
            {
            command.Cancel();  // This saves some post-processing which we do not need (out vars and a row count)
            command.Dispose();
            }
        }
    }

我建议您将这样的操作包装在存储过程中。让它将新记录的ID作为OUT变量返回

…然后可以在SqlCommand的Parameters属性中检索OUT参数。就我个人而言,我喜欢用一种方法来包装它;以下是我使用参数同步执行存储过程的方法,稍微简化:

public static Dictionary<string, object>  ExecSproc(string connectionString, string proc, IEnumerable<SqlParameter> parameters)
    {
    SqlCommand  command = null;
    try
        {
        SqlConnection  connection = GetConnection(connectionString);

        // Build the command
        command                = new SqlCommand(proc, connection);
        command.CommandTimeout = TimeOutSeconds;
        command.CommandType    = CommandType.StoredProcedure;

        // Append parameters
        SqlParameter  retValue = new SqlParameter("Return value", null);
        retValue.Direction = ParameterDirection.ReturnValue;
        command.Parameters.Add(retValue);
        if (parameters != null)
            foreach (SqlParameter param in parameters)
                command.Parameters.Add(param);

        // GO GO GO!
        command.ExecuteNonQuery();

        // Collect the return value and out parameters
        var  outputs = new Dictionary<string, object>();
        foreach (SqlParameter param in command.Parameters)
            if (param.Direction != ParameterDirection.Input)
                outputs.Add(param.ParameterName, param.Value);
        return outputs;
        }
    finally
        {
        if (command != null)
            {
            command.Cancel();  // This saves some post-processing which we do not need (out vars and a row count)
            command.Dispose();
            }
        }
    }

这有点难理解。我可以获得更多的上下文吗?你在说什么价值?我在表单上使用Datagridview作为案例管理工具来选择记录。我希望能够添加记录并立即打开表单。我知道如何打开表单,但不知道如何检索新创建记录的PK。所以,点击按钮,创建记录,检索PK,然后在表单中打开记录就是我想要的。这有点难理解。我可以获得更多的上下文吗?你在说什么价值?我在表单上使用Datagridview作为案例管理工具来选择记录。我希望能够添加记录并立即打开表单。我知道如何打开表单,但不知道如何检索新创建记录的PK。所以点击按钮,创建记录,检索PK,然后在表单中打开记录就是我要做的。最好使用scope\u identity函数,因为@identity可能会被触发器之类的东西更改。好的,我如何从查询中提取值?例如,我将执行类似System.Data.SqlClient.SqlCommand cmd=new System.Data.SqlClient.SqlCommand的操作;cmd.CommandType=System.Data.CommandType.Text;cmd.CommandText=插入PropertyInformation客户端键值1;cmd.CommandText=从属性信息中选择CaseNumberKey,其中RecordID=@@IDENTITY;cmd.Connection=sqlConnection1@korrowan如果CaseNumberKey是一个简单值,通常为int/long,则可以使用ExecuteScalar执行插入并检索该值。否则,或者如果需要多个列,则需要将该命令视为一个查询,并将数据拉回到数据集中。最好使用scope\u identity函数,因为@identity可能会被触发器之类的东西更改。好的,我如何从查询中提取该值?例如,我将执行类似System.Data.SqlClient.SqlCommand cmd=new System.Data.SqlClient.SqlCommand的操作;cmd.CommandType=System.Data.CommandType.Text;cmd.CommandText=插入PropertyInformation客户端键值1;cmd.CommandText=从属性信息中选择CaseNumberKey,其中RecordID=@@IDENTITY;cmd.Connection=sqlConnection1@korrowan如果CaseNumberKey是一个简单值,通常为int/long,则可以使用ExecuteScalar执行插入并检索该值。否则,或者如果需要多个列,则需要将该命令视为查询,并将数据拉回到数据集中。我是否需要引用来运行此操作。我使用system.data,但它似乎还需要其他内容。我是否需要引用才能运行此操作。我使用system.data,但它似乎还需要其他东西。