【问题标题】:Must declare the table variable "@".必须声明表变量“@”。
【发布时间】:2014-02-11 18:59:52
【问题描述】:

我尝试将数据从 DB1 复制到 DB2。但出现错误:必须声明表变量“@TableName”。

这段代码有什么问题?

功能:

  public void TransferData()


    {
        SqlConnection source = new SqlConnection(strConnectDB1);
        SqlConnection destination = new SqlConnection(strConnectDB2);


        source.Open();
        destination.Open();

        SqlCommand cmd= new SqlCommand("SELECT * FROM @TableName", source);

        cmd.Parameters.AddWithValue("@TableName", listbox1.SelectedItem.ToString());
        SqlDataReader reader = cmd.ExecuteReader();


        SqlBulkCopy bulkData = new SqlBulkCopy(destination);

        bulkData.DestinationTableName = listbox1.SelectedItem.ToString();

        bulkData.WriteToServer(reader);

        .
        .


    }

按钮:

    private void button5_Click(object sender, EventArgs e)
    {
        CreateTableName();

        TransferData();

    }

【问题讨论】:

  • 我不认为你可以像这样使用参数作为表名。参数是数据值的占位符,而不是对象名称。
  • @user..您添加的变量是一个表变量..这就是您收到错误的原因..
  • @Yaugen 这是一个完全不同的问题

标签: c#


【解决方案1】:

SQL FROM 子句中的表名不是表达式,因此不能在参数中发送。

需要手动构造SQL字符串,例如

SqlCommand cmd = new SqlCommand(string.Format("SELECT * FROM {0}", listbox1.SelectedItem), source);

强烈建议您对表名进行分隔以防止 SQL 注入攻击。

SqlCommand cmd = new SqlCommand(string.Format("SELECT * FROM {0}", "[" + listbox1.SelectedItem.ToString().Replace("]", "]]") + "]"), source);

【讨论】:

    【解决方案2】:

    您不能对表格使用@Parameter 语法;最好的方法是将表名关闭到 [] 并检查表名是否不包含 [](sql 注入预防措施)

      if (listbox1.SelectedItem.Contains("[") 
         || listbox1.SelectedItem.Contains("]") {
         throw new Exception("Invalid table name");
      }
    
      SqlCommand cmd= new SqlCommand(string.Format(
        "SELECT * FROM [{0}]",listbox1.SelectedItem), source);
    

    【讨论】:

      【解决方案3】:

      试试下面的;将您的 SqlCommand 代码替换为此

      SqlCommand cmd= new SqlCommand("SELECT * FROM " + listbox1.SelectedItem.ToString(), source);

      并删除要添加参数的行。它应该像这样工作。您不能对表使用@Parameter 语法。

      【讨论】:

      • 这是一个 SQL 注入漏洞。至少应将数据库对象名称括起来(在 SQL Server 中使用方括号)。
      【解决方案4】:

      也许你可以试试这个:

      public void TransferData()

      {
      
          string strTableName=string.empty;
          SqlConnection source = new SqlConnection(strConnectDB1);
          SqlConnection destination = new SqlConnection(strConnectDB2);
      
      
          source.Open();
          destination.Open();
      
          SqlCommand cmd= new SqlCommand("SELECT * FROM"+strTableName, source);
      
          strTableName=listbox1.SelectedItem.ToString());
          SqlDataReader reader = cmd.ExecuteReader();
      
      
          SqlBulkCopy bulkData = new SqlBulkCopy(destination);
      
          bulkData.DestinationTableName = listbox1.SelectedItem.ToString();
      
          bulkData.WriteToServer(reader);
      
          .
          .
      
      
      }
      

      希望这会有所帮助..

      【讨论】:

      • 这是一个 SQL 注入漏洞。至少应将数据库对象名称括起来(在 SQL Server 中使用方括号)。
      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多