수색…


소개

ADO (ActiveX Data Objects) .Net은 Microsoft에서 제공하는 도구로 SQL Server, Oracle 및 XML과 같은 데이터 원본에 대한 액세스를 구성 요소를 통해 제공합니다. .Net 프런트 엔드 응용 프로그램은 적절한 권한으로 ADO.Net을 통해 데이터 소스에 연결되면 데이터를 검색, 생성 및 조작 할 수 있습니다.

ADO.Net은 연결없는 아키텍처를 제공합니다. 연결은 전체 세션 동안 유지할 필요가 없으므로 데이터베이스와 상호 작용하는 안전한 방법입니다.

비고

Parameters.AddWithValue 하여 SQL을 Parameters.AddWithValue 하는 것에 대한 참고 사항 : AddWithValue 는 결코 좋은 출발점이 아닙니다. 이 방법은 전달되는 데이터 유형을 유추하는 데 의존합니다. 이렇게하면 변환으로 인해 쿼리에서 색인사용할 수없는 상황이 발생할 수 있습니다. char / varchar (앞에 "n"을 붙이지 않음) 나 date 와 같은 일부 SQL Server 데이터 형식에는 해당 .NET 데이터 형식이 없습니다. 이 경우 올바른 데이터 형식의 Add 를 대신 사용해야합니다 .

SQL 명령문을 명령으로 실행하기

// Uses Windows authentication. Replace the Trusted_Connection parameter with
// User Id=...;Password=...; to use SQL Server authentication instead. You may
// want to find the appropriate connection string for your server.
string connectionString = @"Server=myServer\myInstance;Database=myDataBase;Trusted_Connection=True;"

string sql = "INSERT INTO myTable (myDateTimeField, myIntField) " +
    "VALUES (@someDateTime, @someInt);";

// Most ADO.NET objects are disposable and, thus, require the using keyword.
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
    // Use parameters instead of string concatenation to add user-supplied
    // values to avoid SQL injection and formatting issues. Explicitly supply datatype.

    // System.Data.SqlDbType is an enumeration. See Note1
    command.Parameters.Add("@someDateTime", SqlDbType.DateTime).Value = myDateTimeVariable;
    command.Parameters.Add("@someInt", SqlDbType.Int).Value = myInt32Variable;

    // Execute the SQL statement. Use ExecuteScalar and ExecuteReader instead
    // for query that return results (or see the more specific examples, once
    // those have been added).

    connection.Open();
    command.ExecuteNonQuery();
}

참고 1 : MSFT SQL Server 관련 변형에 대해서는 SqlDbType Enumeration 을 참조하십시오.

참고 2 : MySQL 관련 변형에 대해서는 MySqlDbType 열거 를 참조하십시오.

모범 사례 - SQL 문 실행

public void SaveNewEmployee(Employee newEmployee)
{
    // best practice - wrap all database connections in a using block so they are always closed & disposed even in the event of an Exception
    // best practice - retrieve the connection string by name from the app.config or web.config (depending on the application type) (note, this requires an assembly reference to System.configuration)
    using(SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString))
    {
        // best practice - use column names in your INSERT statement so you are not dependent on the sql schema column order
        // best practice - always use parameters to avoid sql injection attacks and errors if malformed text is used like including a single quote which is the sql equivalent of escaping or starting a string (varchar/nvarchar)
        // best practice - give your parameters meaningful names just like you do variables in your code
        using(SqlCommand sc = new SqlCommand("INSERT INTO employee (FirstName, LastName, DateOfBirth /*etc*/) VALUES (@firstName, @lastName, @dateOfBirth /*etc*/)", con))
        {
            // best practice - always specify the database data type of the column you are using
            // best practice - check for valid values in your code and/or use a database constraint, if inserting NULL then use System.DbNull.Value
            sc.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar, 200){Value = newEmployee.FirstName ?? (object) System.DBNull.Value});
            sc.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar, 200){Value = newEmployee.LastName ?? (object) System.DBNull.Value});

            // best practice - always use the correct types when specifying your parameters, Value is assigned to a DateTime instance and not a string representation of a Date
            sc.Parameters.Add(new SqlParameter("@dateOfBirth", SqlDbType.Date){ Value = newEmployee.DateOfBirth });

            // best practice - open your connection as late as possible unless you need to verify that the database connection is valid and wont fail and the proceeding code execution takes a long time (not the case here)
            con.Open();
            sc.ExecuteNonQuery();
        }

        // the end of the using block will close and dispose the SqlConnection
        // best practice - end the using block as soon as possible to release the database connection
    }
}

// supporting class used as parameter for example
public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

ADO.NET 을 사용하는 최상의 방법

  • 엄지 손가락의 규칙은 최소한의 시간 동안 연결을 여는 것입니다. 프로 시저 실행이 끝나면 연결을 명시 적으로 닫으면 연결 개체가 다시 연결 풀로 반환됩니다. 기본 연결 풀 최대 크기 = 100. 연결 풀링은 SQL Server에 대한 실제 연결 성능을 향상시킵니다. SQL Server의 연결 풀링
  • 사용중인 블록에 모든 데이터베이스 연결을 래핑하여 예외 발생시 항상 닫히고 처리되도록하십시오. 문 사용에 대한 자세한 내용은 문 사용 (C # 참조) 을 참조하십시오.
  • app.config 또는 web.config에서 이름별로 연결 문자열을 검색합니다 (응용 프로그램 유형에 따라 다름).
  • 항상 들어오는 값에 매개 변수 사용
    • SQL 주입 공격 피하기
    • 문자열을 이스케이프 또는 시작하는 것과 동일한 sql 구문 인 작은 따옴표 (varchar / nvarchar)를 포함하는 것과 같이 형식이 잘못된 텍스트를 사용하면 오류를 피하십시오.
    • 데이터베이스 공급자가 모든 데이터베이스 공급자가 지원하지 않는 쿼리 계획을 다시 사용하여 효율성을 높일 수 있도록 허용
  • 매개 변수로 작업 할 때
    • SQL 매개 변수 유형 및 크기 불일치가 삽입 / 업데이트 / 선택 실패의 일반적인 원인입니다.
    • 코드에서 변수를 수행하는 것처럼 Sql 매개 변수에 의미있는 이름을 지정하십시오.
    • 사용중인 열의 데이터베이스 데이터 형식을 지정하면 잘못된 매개 변수 형식이 사용되지 않아 예기치 않은 결과가 발생할 수 있습니다.
    • 명령에 전달하기 전에 들어오는 매개 변수의 유효성을 검사하십시오 ( " 쓰레기 입력, 쓰레기 출력 "과 같이). 가능한 빨리 스택에서 들어오는 값의 유효성 검사
    • 매개 변수 값을 할당 할 때 올바른 유형을 사용하십시오 (예 : DateTime의 문자열 값을 할당하지 말고 실제 DateTime 인스턴스를 매개 변수 값에 할당).
    • 문자열 유형 매개 변수의 크기 를 지정하십시오. 매개 변수의 형식 크기가 일치하면 SQL Server에서 실행 계획을 다시 사용할 수 있기 때문입니다. MAX에 -1을 사용하십시오.
    • AddWithValue 메서드를 사용하지 마십시오. 주된 이유는 필요할 때 매개 변수 유형이나 정밀도 / 크기를 지정하는 것을 잊기 쉽기 때문입니다. 추가 정보는 AddWithValue 사용을 이미 중단 할 수 있습니까?를 참조하십시오 .
  • 데이터베이스 연결을 사용할 때
    • 연결을 가능한 한 늦게 열고 가능한 한 빨리 닫으십시오. 외부 리소스로 작업 할 때 일반적인 지침입니다.
    • 데이터베이스 연결 인스턴스를 절대 공유하지 마십시오 (예 : 단일 호스트가 SqlConnection 유형의 공유 인스턴스를 가짐). 필요한 경우 코드가 항상 새 데이터베이스 연결 인스턴스를 만든 다음 호출 코드를 처리하고 완료되면 "버려 버리십시오". 그 이유는
      • 대부분의 데이터베이스 공급자에는 일종의 연결 풀이 있으므로 새로운 관리 연결을 만드는 것이 저렴합니다.
      • 코드가 여러 스레드로 작업하기 시작하면 이후의 오류를 제거합니다.

공통 인터페이스를 사용하여 공급 업체별 클래스를 추상화합니다.

var providerName = "System.Data.SqlClient";    //Oracle.ManagedDataAccess.Client, IBM.Data.DB2
var connectionString = "{your-connection-string}";
//you will probably get the above two values in the ConnectionStringSettings object from .config file

var factory = DbProviderFactories.GetFactory(providerName);
using(var connection = factory.CreateConnection()) {    //IDbConnection
    connection.ConnectionString = connectionString;
    connection.Open();
    
    using(var command = connection.CreateCommand()) {    //IDbCommand
        command.CommandText = "{query}";
        
        using(var reader = command.ExecuteReader()) {    //IDataReader
            while(reader.Read()) {
                ...
            }
        }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow