패라메트릭 SQL 문

5712 단어 ql 문장
SQL 주입을 피하는 방법은 두 가지가 있다. 하나는 모든 SQL 문장을 저장 과정에 저장하는 것이다. 이렇게 하면 SQL 주입을 피할 수 있을 뿐만 아니라 성능도 향상시킬 수 있다. 또한 저장 과정은 전문적인 데이터베이스 관리자(DBA)가 작성하고 집중적으로 관리할 수 있다. 그러나 이런 방법은 때때로 같은 몇 개의 표에 대해 서로 다른 조건을 가진 조회를 할 수 있다. SQL 문장은 다를 수 있고 이렇게 하면 대량의 저장 과정을 작성할 수 있다.그래서 어떤 사람들은 두 번째 방안인 매개 변수화 SQL 문장을 제기했다.예를 들어 이 편에서 작성한 표 UserInfo에서 모든 여성 사용자를 찾을 경우 일반적으로 SQL 문은 다음과 같습니다.
 select * from UserInfo where sex=0


패라메트릭 SQL 문에서 수치는 패라메트릭 형식으로 제공되며, 위의 질의에 대해 패라메트릭 SQL 문은 다음과 같이 표시됩니다.
 select * from UserInfo where sex=@sex


코드에서 이 SQL 문장의 매개 변수에 값을 부여합니다. 만약 우리가 UserInfo표에서 30세 이상의 남성 사용자를 찾으려면 이 매개 변수화 SQL 문장은 이렇게 쓸 수 있습니다.
select * from UserInfo where sex=@sex and age>@age


다음은 이 질의를 수행하고 질의 결과 세트를 DataTable로 반환하는 코드입니다.
//   Connection   

SqlConnection connection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=''"); 

//   Command   

SqlCommand command = new SqlCommand("select * from UserInfo where sex=@sex and age>@age", connection); 

//             

command.Parameters.AddWithValue("@sex", true); 

//             

SqlParameter parameter = new SqlParameter("@age", SqlDbType.Int);//  UserInfo  age   int    

parameter.Value = 30; 

command.Parameters.Add(parameter);//     

//   DataAdapter 

SqlDataAdapter adapter = new SqlDataAdapter(command); 

DataTable data = new DataTable();


위 코드는 SQL Server 데이터베이스에 액세스하는 코드입니다.만약에 본고에서 언급한 데이터가 각각 Access, MySQL, Oracle 데이터베이스에 있다면 대응하는 매개 변수화 SQL 문장과 매개 변수는 각각 다음과 같다.
데이터베이스
Access
MySQL
Oracle
SQL 문
select * from UserInfo where sex=? and age>?
select * from UserInfo where sex=?sex and age>?age
select * from UserInfo where sex=:sex and age>:age
매개 변수
OleDbParameter
MySqlParameter
OracleParameter
인스턴스화 매개변수
OleDbParameter p=new OleDbParameter(“?”, OleDbType. Boolean);
MySqlParameter p=new MySqlParameter(“?sex”, MySqlDbType.Bit);
OracleParameter p=new OracleParameter(“:sex”, OracleType.Byte);
할당액
p.Value=true;
p.Value=1;
p.Value=1;
위의 실례 코드를 통해 알 수 있듯이 SQL 문장은 대체적으로 비슷하지만 서로 다른 데이터베이스의 특징에서 파라미터화된 SQL 문장이 다를 수 있다. 예를 들어Access에서 파라미터화된 SQL 문장은 파라미터가 직접적으로'?'매개 변수 이름으로 SQL Server에서는 매개 변수에 "@"접두사가 있고 MySQL에서는 매개 변수에 "?"접두어, Oracle의 매개 변수는 ":"을 접두어로 합니다.참고: Access에서 매개변수 이름이 모두?이므로따라서 매개 변수에 값을 부여하려면 반드시 열 순서에 따라 값을 부여해야 한다. 그렇지 않으면 오류가 발생할 수 있다.
 
Command 개체 전송 효율성 테스트
에 있습니다.net 플랫폼, 일반적인 insert 문장은 두 가지 쓰기 방법이 있는데 파라미터가 없는 insert into test(c1,c2)values(var1,var2)와 파라미터가 있는 insert into test(c1,c2)values(:c1,:c2)가 있는데 그들의 실행 효율은 어떻습니까?테스트를 했는데 코드는 다음과 같다. (데이터베이스는oracle이다)
public partial class WebForm1 : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            //test1();

            test2();

        }

        private void test1()

        {

            OracleConnection con = new OracleConnection();

            con.ConnectionString = "Data Source=oracl;User Id=xxx;Password=xxx;Persist Security Info=True;";

            System.Random r = new Random((int)System.DateTime.Now.Ticks);

            string strCommand = "insert into test(c1,c2) values({0},{1})";

            OracleCommand com = new OracleCommand();

            com.Connection = con;

            con.Open();

            DateTime dt = DateTime.Now;

            Label1.Text = "   :"+DateTime.Now.ToLongTimeString();

            for (int i = 0; i < 50000; i++)

            {



                com.CommandText = string.Format(strCommand, r.Next(), r.Next());

                com.ExecuteNonQuery();

            }

            com.CommandText = "truncate table test";

            com.ExecuteNonQuery();

            con.Close();

            Label2.Text = DateTime.Now.ToLongTimeString();

        }

        private void test2()

        {

            OracleConnection con = new OracleConnection();



            con.ConnectionString = "Data Source=bocodb;User Id=hljyd;Password=hljyd;Persist Security Info=True;";

            System.Random r = new Random((int)System.DateTime.Now.Ticks);

            string strCommand = "insert into test(c1,c2) values(:c1,:c2)";

            OracleCommand com = new OracleCommand();

            com.Parameters.Add(":c1", OracleType.Number);

            com.Parameters.Add(":c2", OracleType.Number);

            com.CommandText = strCommand;

            com.Connection = con;

            con.Open();

            Label1.Text = "  :"+DateTime.Now.ToLongTimeString();

            for (int i = 0; i < 50000; i++)

            {

                com.Parameters[":c1"].Value = r.Next();

                com.Parameters[":c2"].Value = r.Next();

                

                com.ExecuteNonQuery();

            }

            com.Parameters.Clear();

            com.CommandText = "truncate table test";

            com.ExecuteNonQuery();

            con.Close();

            Label2.Text = DateTime.Now.ToLongTimeString();

        }

    }


실행 결과: 10000 기록: 매개 변수를 전달하지 않습니까?5:46:19 15:46:34 15초 전파 매개 변수:?5:50:51 15:51:01 10초 50000 기록: 전송하지 않는 파라미터 16:09:03 16:10:24 81초 전송: 16:15:43 16:16:36 53초 이것은 단지 2개의 파라미터일 뿐입니다. 파라미터가 많으면 더 큰 영향을 주지 않을까요?10000기록, 7개 매개 변수: 전송하지 않는 매개 변수: 17:11:01 17:11:18 17초 전송 매개 변수: 17:13:59 13초 50000 기록: 7개 매개 변수: 전송하지 않는 매개 변수: 17:19:02 17:20:25 1분 23초 전송 매개 변수: 17:15:09 17:16:10 1분 1초는 차이가 크지 않지만command 대상에게 전송하는 매개 변수는 sql 주입 문제를 피할 수 있을 뿐만 아니라 성능도 향상시킬 수 있다.

좋은 웹페이지 즐겨찾기