2014-03-03 1 views
0

SQL Server 데이터베이스에 1 또는 0을 삽입하려고하는데 데이터 형식이 "비트"입니다. 내가이 일을 시도했지만 그것은 어디 내가 잘못하고있는 중이 야확인란을 선택하면 비트 형식 필드에 대해 Sql Server에 1 또는 0을 삽입하는 방법은 무엇입니까?

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() + "'" 
      ) ; 

나를 안내하시기 바랍니다 어디에 - 근처의 구문이 잘못되었습니다 말한다?

+0

리플 로우 코드입니다. 왼쪽 구문 오류가 손상되지 않았습니다. –

+4

데이터 값을 절대 그런 식으로 연결하지 마십시오. ** 항상 ** 매개 변수화 된 쿼리를 사용하십시오. – Alejandro

+0

SQL이 작동하지 않기 때문에 SQL 명령 프롬프트 (예 : SQL Management Studio)로 이동하여 직접 명령을 입력하십시오. 애플리케이션 코드에서 여분의 레이어를 통과하는 것보다 디버깅하는 것이 훨씬 쉽습니다. 또한 알레한드로가 말한 것을 되풀이합니다. 사용중인 클라이언트 측 기법은 SQL 삽입 공격에 취약합니다. 누군가가 "log"세션 변수의 이름을 다음과 같이 변경하면 어떨까요 : ' '; tbl에서 삭제; - ' – catfood

답변

5

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()+"'"); 

에 초기 가능한 해결책이지만 Session["log"]의 연결에 큰 문제가있다. 에 취약하기 때문에 sql 명령을 형성하기 위해 문자열 값 (아마도 사용자 입력으로 설정)을 연결하는 것은 매우 나쁜 습관입니다. 따라서 매개 변수 목록을 수신하려면 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(); 
    } 
} 

처럼 뭔가에 ExecDB을 변경하고 ExecDB에 전달

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 [email protected]", ps); 

List<SqlParameter> 매개 변수를 호출하는 것이 좋습니다, 따라서, 선택 사항입니다 ExecDB를 호출하면 매개 변수 컬렉션이 필요하지 않으므로 코드를 그대로 둘 수 있습니다.

+0

스티브에게 고마워. 귀하의 제안은 매우 도움이되었습니다.고마워요 형제 :-) – Omi

1

보자 :

  1. 귀하의 C# 코드 샘플도 컴파일되지 않습니다.
  2. SQL 삽입 공격에 취약한 구성 동적 SQL
  3. SQL insert 쿼리는 구문 상 유효하지 않으며 컴파일 할 코드가 있으면 오류가 발생합니다. 그가 수정된다고 가정

, bool에서 /에 CLR지도 SQL 서버의 bit 데이터 타입 (일명 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 ; 
} 
+0

고마워 니콜라스 씨. 당신의 제안은 또한 매우 적절하고 유용했습니다 :-) 감사합니다 :-) – Omi