C# 如果选中复选框,如何在Sql Server中为位类型字段插入1或0?

C# 如果选中复选框,如何在Sql Server中为位类型字段插入1或0?,c#,sql-server,checkbox,bit,C#,Sql Server,Checkbox,Bit,我正在尝试在SQL Server数据库中插入1或0,并且我的数据类型为“bit”。 我试过这样做,但它说不正确的语法附近的地方- dt=g1.ExecDB( insert into tbl ("check1,check2,check3") values('" + Convert.ToByte(check1.Checked) + "','" + Convert.ToByte(check2.Checked) + "','" +

我正在尝试在SQL Server数据库中插入1或0,并且我的数据类型为“bit”。 我试过这样做,但它说不正确的语法附近的地方-

dt=g1.ExecDB( insert into tbl ("check1,check2,check3") values('"
            + Convert.ToByte(check1.Checked) + "','"
            + Convert.ToByte(check2.Checked) + "','"
            + Convert.ToByte(check3.Checked) + "' ) )
              where loginname = '"+Session["log"].ToString() + "'"
            ) ;

请告诉我哪里做错了?

在sql字符串中添加复选框的名称无法工作,当然也不能对它们调用Convert.ToByte。通过这种方式,您只需在字符串中插入控件的名称和应转换其值的函数的名称。当然,对于数据库的SQL解析器来说,这只是一个无效的SQL命令

相反,您应该尝试从C#代码创建有效的SQL命令来解决问题。这是您问题的初始可能解决方案

dt=g1.ExecDB("insert into tbl (check1,check2,check3) values(" + 
             (check1.Checked ? "1" : "0") + ", " + 
             (check2.Checked ? "1" : "0") + ", " + 
             (check3.Checked ? "1" : "0") + 
             ") where loginname='"+Session["log"].ToString()+"'");
但是
会话[“log”]
的串联存在一个大问题。 连接字符串值(可能是由用户输入设置的)以形成sql命令是一种非常糟糕的做法,因为它容易受到攻击。因此,必须更改
ExecDB
以接收参数列表

我建议把你的ExecDB改成这样

public int ExecDB(string query, List<SqlParameter>parameters = null)
{
     using(SqlConnection cn = new SqlConnection(connString))
     using(SqlCommand cmd = new SqlCommand(query, cn))
     {
         cn.Open();
         if(parameters != null && parameters.Count > 0)
             cmd.Parameters.AddRange(parameters.ToArray());
         return cmd.ExecuteNonQuery();
     }
 }
public int ExecDB(字符串查询,Listparameters=null)
{
使用(SqlConnection cn=newsqlconnection(connString))
使用(SqlCommand cmd=newsqlcommand(query,cn))
{
cn.Open();
if(parameters!=null&¶meters.Count>0)
cmd.Parameters.AddRange(Parameters.ToArray());
返回cmd.ExecuteNonQuery();
}
}
并称之为

List<SqlParameter> ps = new List<SqlParameter>();
SqlParameter p = new SqlParameter("@login", Session["log"].ToString());
ps.Add(p);
dt=g1.ExecDB("insert into tbl (check1,check2,check3) values(" + 
             (check1.Checked ? "1" : "0") + ", " + 
             (check2.Checked ? "1" : "0") + ", " + 
             (check3.Checked ? "1" : "0") + 
             ") where loginname=@login", ps);
List ps=new List();
SqlParameter p=newsqlparameter(“@login”,Session[“log”].ToString());
ps.Add(p);
dt=g1.ExecDB(“插入到tbl(检查1、检查2、检查3)值中”(+
(选中1。选中?“1”:“0”)+,“+
(勾选2.勾选?“1”:“0”)+,“+
(勾选3.勾选?“1”:“0”)+
)其中loginname=@login“,ps);

传递给ExecDB的
列表
参数是可选的,因此,如果有任何代码调用ExecDB时不需要参数集合,则可以保持代码现在的状态。

在sql字符串中添加复选框的名称是不可行的,当然也不能对它们调用Convert.ToByte。通过这种方式,您只需在字符串中插入控件的名称和应转换其值的函数的名称。当然,对于数据库的SQL解析器来说,这只是一个无效的SQL命令

相反,您应该尝试从C#代码创建有效的SQL命令来解决问题。这是您问题的初始可能解决方案

dt=g1.ExecDB("insert into tbl (check1,check2,check3) values(" + 
             (check1.Checked ? "1" : "0") + ", " + 
             (check2.Checked ? "1" : "0") + ", " + 
             (check3.Checked ? "1" : "0") + 
             ") where loginname='"+Session["log"].ToString()+"'");
但是
会话[“log”]
的串联存在一个大问题。 连接字符串值(可能是由用户输入设置的)以形成sql命令是一种非常糟糕的做法,因为它容易受到攻击。因此,必须更改
ExecDB
以接收参数列表

我建议把你的ExecDB改成这样

public int ExecDB(string query, List<SqlParameter>parameters = null)
{
     using(SqlConnection cn = new SqlConnection(connString))
     using(SqlCommand cmd = new SqlCommand(query, cn))
     {
         cn.Open();
         if(parameters != null && parameters.Count > 0)
             cmd.Parameters.AddRange(parameters.ToArray());
         return cmd.ExecuteNonQuery();
     }
 }
public int ExecDB(字符串查询,Listparameters=null)
{
使用(SqlConnection cn=newsqlconnection(connString))
使用(SqlCommand cmd=newsqlcommand(query,cn))
{
cn.Open();
if(parameters!=null&¶meters.Count>0)
cmd.Parameters.AddRange(Parameters.ToArray());
返回cmd.ExecuteNonQuery();
}
}
并称之为

List<SqlParameter> ps = new List<SqlParameter>();
SqlParameter p = new SqlParameter("@login", Session["log"].ToString());
ps.Add(p);
dt=g1.ExecDB("insert into tbl (check1,check2,check3) values(" + 
             (check1.Checked ? "1" : "0") + ", " + 
             (check2.Checked ? "1" : "0") + ", " + 
             (check3.Checked ? "1" : "0") + 
             ") where loginname=@login", ps);
List ps=new List();
SqlParameter p=newsqlparameter(“@login”,Session[“log”].ToString());
ps.Add(p);
dt=g1.ExecDB(“插入到tbl(检查1、检查2、检查3)值中”(+
(选中1。选中?“1”:“0”)+,“+
(勾选2.勾选?“1”:“0”)+,“+
(勾选3.勾选?“1”:“0”)+
)其中loginname=@login“,ps);
传递给ExecDB的
列表
参数是可选的,因此,如果您有调用ExecDB不需要参数集合的代码,您可以保持代码不变。

让我们看看:

  • 您的C#代码示例甚至无法编译
  • 您正在构建易受sql注入攻击的动态sql
  • SQL
    insert
    查询在语法上无效,如果要编译代码,将抛出错误
  • 假设这些都已更正,CLR将SQL Server的
    数据类型映射到
    bool
    (又称
    System.Boolean
    )。所以

    试着这样做:

    const string @insertQuery = @"
      insert tbl ( check1 , check2 , check3 )
      select @p1 , @p2 , @p3
      where loginname = @login
      " ;
    
    using ( SqlConnection conn = GetSqlConnection() )
    using ( SqlCommand cmd = conn.CreateCommand() )
    {
    
      cmd.CommandText = insertQuery ;
      cmd.CommandType = CommandType.Text;
      cmd.Parameters.AddWithValue( "@p1"    , check1.Checked ) ;
      cmd.Parameters.AddWithValue( "@p2"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@p3"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@login" , (string) Session["log"] ) ;
    
      conn.Open();
      int rowsAffected = cmd.ExecuteNonQuery() ;
      conn.Close() ;
    
      bool success ;
      if      ( rowsAffected == 0 ) success = false ;
      else if ( rowsAffected == 1 ) success = true ;
      else throw new InvalidOperationException() ;
    
      return success ;
    }
    
    让我们看看:

  • 您的C#代码示例甚至无法编译
  • 您正在构建易受sql注入攻击的动态sql
  • SQL
    insert
    查询在语法上无效,如果要编译代码,将抛出错误
  • 假设这些都已更正,CLR将SQL Server的
    数据类型映射到
    bool
    (又称
    System.Boolean
    )。所以

    试着这样做:

    const string @insertQuery = @"
      insert tbl ( check1 , check2 , check3 )
      select @p1 , @p2 , @p3
      where loginname = @login
      " ;
    
    using ( SqlConnection conn = GetSqlConnection() )
    using ( SqlCommand cmd = conn.CreateCommand() )
    {
    
      cmd.CommandText = insertQuery ;
      cmd.CommandType = CommandType.Text;
      cmd.Parameters.AddWithValue( "@p1"    , check1.Checked ) ;
      cmd.Parameters.AddWithValue( "@p2"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@p3"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@login" , (string) Session["log"] ) ;
    
      conn.Open();
      int rowsAffected = cmd.ExecuteNonQuery() ;
      conn.Close() ;
    
      bool success ;
      if      ( rowsAffected == 0 ) success = false ;
      else if ( rowsAffected == 1 ) success = true ;
      else throw new InvalidOperationException() ;
    
      return success ;
    }
    

    从c#在数据库表中插入位值:

    使用如下sql参数:

    const string @insertQuery = @"
      insert tbl ( check1 , check2 , check3 )
      select @p1 , @p2 , @p3
      where loginname = @login
      " ;
    
    using ( SqlConnection conn = GetSqlConnection() )
    using ( SqlCommand cmd = conn.CreateCommand() )
    {
    
      cmd.CommandText = insertQuery ;
      cmd.CommandType = CommandType.Text;
      cmd.Parameters.AddWithValue( "@p1"    , check1.Checked ) ;
      cmd.Parameters.AddWithValue( "@p2"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@p3"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@login" , (string) Session["log"] ) ;
    
      conn.Open();
      int rowsAffected = cmd.ExecuteNonQuery() ;
      conn.Close() ;
    
      bool success ;
      if      ( rowsAffected == 0 ) success = false ;
      else if ( rowsAffected == 1 ) success = true ;
      else throw new InvalidOperationException() ;
    
      return success ;
    }
    

    SqlParameter=newsqlparameter(“@check1”,Convert.ToBoolean(0))

    从c#在数据库表中插入位值:

    使用如下sql参数:

    const string @insertQuery = @"
      insert tbl ( check1 , check2 , check3 )
      select @p1 , @p2 , @p3
      where loginname = @login
      " ;
    
    using ( SqlConnection conn = GetSqlConnection() )
    using ( SqlCommand cmd = conn.CreateCommand() )
    {
    
      cmd.CommandText = insertQuery ;
      cmd.CommandType = CommandType.Text;
      cmd.Parameters.AddWithValue( "@p1"    , check1.Checked ) ;
      cmd.Parameters.AddWithValue( "@p2"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@p3"    , check2.Checked ) ;
      cmd.Parameters.AddWithValue( "@login" , (string) Session["log"] ) ;
    
      conn.Open();
      int rowsAffected = cmd.ExecuteNonQuery() ;
      conn.Close() ;
    
      bool success ;
      if      ( rowsAffected == 0 ) success = false ;
      else if ( rowsAffected == 1 ) success = true ;
      else throw new InvalidOperationException() ;
    
      return success ;
    }
    

    SqlParameter=newSQLParameter(“@check1”,Convert.ToBoolean(0))

    回流代码。保留语法错误不变。永远不要像那样将数据值连接到查询,始终使用参数化查询。由于SQL不起作用,请转到SQL命令提示符(例如在SQL Management Studio中)并直接输入命令。通过这种方式进行调试比通过应用程序代码中的额外层要容易得多。同时,也呼应了亚历杭德罗的话。您使用的客户端技术容易受到SQL注入攻击。如果有人将“log”会话变量的名称更改为:
    ;从tbl中删除--回流代码。保留语法错误不变。永远不要像那样将数据值连接到查询,始终使用参数化查询。因为