【问题标题】:Using select scoped value in insert statements?在插入语句中使用选择范围值?
【发布时间】:2011-05-09 07:56:40
【问题描述】:

注意:我正在构建一个练习项目,我的培训师禁止我进行参数化。我知道安全风险,但不会部署该站点。我正在使用 select scope_identity 方法从我的表 Submissions 的 SubmissionId 列中获取一个自动递增的值。

我想将该值插入到另外两个表中;我已将 newSubID 声明为 var,并在插入语句中使用它,但收到错误消息

在此上下文中不允许使用名称“newSubID”。有效表达式是常量、常量表达式和(在某些情况下)变量。不允许使用列名。

我在这里错过了什么?

这是我的代码:

protected void BtnSubmit_Click(object sender, EventArgs e)
{
    string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
    String subQuery = "INSERT INTO Submission (Coverage, CurrentCoverage, PrimEx, Retention, EffectiveDate, Commission, Premium, Comments) VALUES ('" + TbCoverage.Text + "','" + TbCurrentCoverage.Text + "','" + TbPrimEx.Text + "','" + TbRetention.Text + "','" + TbEffectiveDate.Text + "','" + TbCommission.Text + "','" + TbPremium.Text + "','" + TbComments.Text + "')"
        + "SELECT CAST (SCOPE_IDENTITY() AS int)";

    using (SqlConnection sqlConn = new SqlConnection(connectionString))
    {
        sqlConn.Open();
        SqlCommand subCmd = new SqlCommand(subQuery, sqlConn);

        using (subCmd)
        {
            subCmd.ExecuteNonQuery();
            var newSubID = (Int32)subCmd.ExecuteScalar();

            String custQuery = "INSERT INTO Customer (CustId, CustName, SicNaic, CustAdd, CustCity, CustState, CustZip, SubId) VALUES ('" + TbCustId.Text + "', '" + TbCustName.Text + "', '" + RblSicNaic.SelectedItem + "', '" + TbCustAddress.Text + "', '" + TbCustCity.Text + "', '" + DdlCustState.SelectedItem + "', '" + TbCustZip.Text + "', newSubID)";
            String broQuery = "INSERT INTO Broker (BroId, BroName, BroAdd, BroCity, BroState, BroZip, EntityType, SubId) VALUES ('" + TbBroId.Text + "', '" + TbBroName.Text + "', '" + TbBroAddress.Text + "', '" + TbBroCity.Text + "', '" + DdlBroState.SelectedItem + "', '" + TbBroZip.Text + "', '" + DdlEntity.SelectedItem + "', newSubID)";
            SqlCommand custCmd = new SqlCommand(custQuery, sqlConn);
            SqlCommand broCmd = new SqlCommand(broQuery, sqlConn);
            using (custCmd)
            using (broCmd)
            {
                custCmd.ExecuteNonQuery();
                broCmd.ExecuteNonQuery();
                Response.Redirect("~/View.aspx?ProductId=" + newSubID);
            }

这是在下一页上调用的(我留下了错误,因为它们是为了帮助任何可能需要查看问题和解决方案的人,这些问题和解决方案列在下面的答案中):

string x = Request.QueryString["SubmissionId"];
string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
string editCustQuery = "SELECT CustName, SicNaic, CustCity, CustAdd, CustState, CustZip FROM Customer WHERE SubId =" + x;
using (SqlConnection editConn = new SqlConnection(connectionString))
{
    editConn.Open();

    using (SqlCommand CustCommand = new SqlCommand(editCustQuery, editConn))
    {
        SqlDataReader dr = CustCommand.ExecuteReader();
        dr.Read();
        LblCustName.Text = dr.GetString(0);
        LblSicNaic.Text = dr.GetString(1);
        LblCustCity.Text = dr.GetString(2);
        LblCustAddress.Text = dr.GetString(3);
        LblCustState.Text = dr.GetString(4);
        LblCustZip.Text = dr.GetInt32(5).ToString();
    }

【问题讨论】:

  • @ibram,不会超出范围(我认为这是用花括号关闭代码块的正确术语)自动关闭阅读器?
  • 你应该戴头盔。不会的。

标签: c# asp.net sql-server visual-studio


【解决方案1】:

这是因为您没有将 newSubID 连接到 custQuery / btoQuery SQL 语句中,而是在语句中使用文字文本“newSubID”,这在此处无效,因为它将假定“newSubID”是列名。

String custQuery = "INSERT INTO Customer (CustId, CustName, SicNaic, CustAdd, CustCity,
    CustState, CustZip, SubId) 
VALUES ('" + TbCustId.Text + "', '" + TbCustName.Text + "', '" + RblSicNaic.SelectedItem +   
    "', '" + TbCustAddress.Text + "', '" + TbCustCity.Text + "', '" + 
    DdlCustState.SelectedItem + "', '" + TbCustZip.Text + "'," + 
    newSubID.toString() + ")";

当然,由于您的免责声明,我只给出一个使用动态 SQL 的答案,而不是我在现实生活中会做的事情!

【讨论】:

  • 当然。非常感谢,@Ada。如果您不介意后续问题,我的重定向行对您来说是否正确,或者我是否也需要将其连接起来?我在重定向页面上抛出错误。
  • @Brazos - Response.Redirect("~/View.aspx?ProductId=" + newSubID.toString()) - 如果 View.aspx 在加载时出错,那么你有一个错误没有看到就无法分辨的页面
  • 我认为可能是这样。我正在使用这个 'string x = Request.QueryString["SubmissionId"];字符串 connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;字符串editCustQuery =“选择CustName,SicNaic,CustCity,CustAdd,CustState,CustZip FROM Customer WHERE SubId =”+ x;'调用右行,然后显示数据读取器。我很确定数据读取器没问题。我的请求查询是否还有另一个明显的问题?
  • @Brazos - 假设 SubId 是数据库中的一个 INTEGER,假设 x 变量确实包含一个值(即 Request.QueryString["SubmissionId"] 确实给你一个值),看起来没问题。
  • @Ada,是的,SubId 是数据库中的一个 INT。又一个愚蠢的问题,但我将如何确定 x 是否包含一个值? SubId 在 Submission 表中自动递增,因此我没有在插入命令中的该列中插入任何内容。我收到的错误消息是“SqlDataReader dr = CustCommand.ExecuteReader(); 行上 '=' 附近的语法不正确。
【解决方案2】:
  1. AdaTheDev 的答案是正确的。
  2. 我认为您还有另一个问题。如果您使用相同的命令执行 ExecuteNonQuery 和 ExecuteScalar,您将插入两次。为您的 scope_id 使用 out-parameter 并仅调用 exenonquery 或仅调用 exescalar。

            //subCmd.ExecuteNonQuery();
            var newSubID = (Int32)subCmd.ExecuteScalar();
    

【讨论】:

  • 谢谢,@ibram。这可能是一个愚蠢的问题,但如果我抛弃了 exenonquery,我是否仍会在命令中插入所有其他值,或者只是使用 execscalar 调用该值?
  • 所有的 sql 代码都将按照一个顺序完成,就像你的一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
相关资源
最近更新 更多